在postgres中进行并发更新时,我得到了一个
错误:由于并发更新而无法序列化访问
有没有办法让事务等到另一个事务完成,而不是因为错误而失败?
这是我的测试用例:
-- SESSION 1
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL Serializable;
SELECT pg_sleep(5); -- 5 second delay
UPDATE users SET nonce = nonce + 1 WHERE u_id = 'dude';
COMMIT;
和另一个会话(会话2)同时发生
-- SESSION 2
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL Serializable;
UPDATE users SET nonce = nonce + 1 WHERE u_id = 'dude';
COMMIT;
如何让事务在执行前等待上一个事务完成。截至目前,它将不会执行,它只会报告错误,这使我在我的服务器上管理故障逻辑。有什么像我可以使用的交易队列吗?或者也许是一个声明,检查是否有其他事务正在进行,然后等待它解决?
(注意:我正在使用postgres,我的事务隔离设置为可序列化)
编辑:
我通过做一些小修改解决了这个问题。 我将事务隔离更改为Read committed,并在更新语句后移动了5秒延迟。
延迟在更新语句之后非常重要,因为数据库在读取更新语句之前不会在行上放置块。
以下是修订后的测试用例:
-- SESSION 1
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL Read committed;
UPDATE users SET nonce = nonce + 1 WHERE u_id = 'dude';
SELECT pg_sleep(5); -- 5 second delay
COMMIT;
和另一个会话(会话2)同时发生
-- SESSION 2
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL Read committed;
UPDATE users SET nonce = nonce + 1 WHERE u_id = 'dude';
COMMIT;
在此方案中,会话2事务在提交自身之前等待会话1事务提交。
答案 0 :(得分:0)
您已设置Serializable
隔离级别,这意味着只要事务无法序列化 - 那么它就会失败。
这就是它的设计工作方式。
而且,不,你不能改变它的行为。