gpt4 book ai didi

postgresql - SKIP LOCKED 除非所有行都被锁定

转载 作者:行者123 更新时间:2023-11-29 12:09:40 26 4
gpt4 key购买 nike

有没有一种方法可以使用 SKIP LOCKED 对 PostgreSQL 进行查询以避免获取已锁定的行,但同时如果所有内容都已锁定以等待第一个解锁行?

在我的用例中,我想避免在请求可用电话号码时出现误报。但是在我锁定所有号码的情况下,这不太可能,但它仍然可能发生并且应该解决。

SELECT plain_number FROM pool
ORDER BY RANDOM()
LIMIT 1
FOR UPDATE
SKIP LOCKED

最佳答案

这似乎可行:

WITH sl AS (
SELECT plain_number FROM pool ORDER BY random() LIMIT 1 FOR UPDATE SKIP LOCKED
),
fu AS (
SELECT plain_number FROM pool WHERE NOT EXISTS(SELECT 1 FROM sl) ORDER BY random() LIMIT 1 FOR UPDATE
)
SELECT * FROM sl FULL JOIN fu USING (plain_number);

但是,它会等待一个随机的 plain_number 来释放它的锁。我认为不可能等待第一个锁被释放。

设置:

create table pool(
plain_number text primary key
);

insert into pool(plain_number)
select generate_series(1, 9)::text;

这是我为测试编写的一个小 node.js 脚本:

const pg = require("pg");
const options = {
"user": "test",
"password": "test",
"database": "test"
};

function thread_ish() {
const client = new pg.Client(options);
const end = client.end.bind(client);
const rollback = function (client) {
client.query("ROLLBACK", end);
};

client.connect(function () {
client.query("BEGIN", function (err) {
if (err) {
console.error(err);
return rollback(client);
}
client.query(
"WITH sl AS ("
+ " SELECT plain_number FROM pool ORDER BY random() LIMIT 1 FOR UPDATE SKIP LOCKED"
+ "), fu AS ("
+ " SELECT plain_number FROM pool WHERE NOT EXISTS(SELECT 1 FROM sl) ORDER BY random() LIMIT 1 FOR UPDATE"
+ ")"
+ "SELECT * FROM sl FULL JOIN fu USING (plain_number)",
function (err, result) {
if (err) {
console.error(err);
return rollback(client);
}

console.log("Selected number is", result.rows);
setTimeout(function () {
client.query("COMMIT", end);
}, 1000);
}
);
});
});
}

for (var i = 0; i < 13; ++i) {
setTimeout(thread_ish, Math.random() * 100);
}

关于postgresql - SKIP LOCKED 除非所有行都被锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43331442/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com