首页 > 解决方案 > PostgreSQL 11 中的并发更新

问题描述

我有大约 10 个查询同时更新一行,所以我想知道两者之间有什么区别

UPDATE account SET balance = balance + 1000
WHERE id = (SELECT id FROM account
            where id = 1 FOR UPDATE);

BEGIN;

SELECT balance FROM account WHERE id = 1 FOR UPDATE;

-- compute $newval = $balance + 1000

UPDATE account SET balance = $newval WHERE id = 1;

COMMIT;

我正在使用 PosgreSQL 11,那么正确的解决方案是什么?这两个解决方案中的多事务会发生什么?

标签: postgresqlconcurrencytransactionspostgresql-11

解决方案


两个版本将具有完全相同的效果,并且都防止面对并发异常,因为行在被修改之前被锁定。

第一种方法更可取,因为只有一次客户端-服务器往返,所以事务更短,持有锁的时间更短,提高了并发性。

做到这一点并避免并发数据修改的最佳方法是:

UPDATE account
SET balance = balance + 1000
WHERE id = 1;

This does the same, because an UPDATE automatically puts an exclusive lock on the affected row, and a blocked query will see the updated version of the row when the lock is gone.


推荐阅读