PostgreSQL 11 中的并发更新

Concurrent update in 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,那么正确的解决方案是什么?这两种解决方案中的多事务会发生什么情况?

两个版本的效果是完全一样的,都是在并发时防止异常,因为行在修改之前是锁住的。

第一种方式更可取,因为只有一次client-server往返,所以事务更短,锁持有时间更短,提高了并发性。

执行此操作并避免并发数据修改的最佳方法是:

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

这也是一样的,因为 UPDATE 会自动在受影响的行上放置排他锁,当锁消失时,阻塞的查询将看到该行的更新版本。