Postgres等待交易完成

时间:2015-06-05 01:54:42

标签: database postgresql transactions

在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事务提交。

1 个答案:

答案 0 :(得分:0)

您已设置Serializable隔离级别,这意味着只要事务无法序列化 - 那么它就会失败。

这就是它的设计工作方式。

而且,不,你不能改变它的行为。