【发布时间】:2020-06-06 05:59:18
【问题描述】:
假设我有一组代码创建一个事务,选择、删除和重新创建一个资源,并提交,以便更新它:
BEGINSELECT * FROM "product" WHERE (code = 'A') FOR UPDATEDELETE FROM "product" WHERE "product"."id" = 1INSERT INTO "product" ("id","code","price") VALUES (1,'A',3000) // Updated priceCOMMIT
现在,假设这段代码同时运行两次,并试图修改同一行:
TX1 - BEGIN
TX1 - SELECT product
TX1 - DELETE product
TX2 - BEGIN
TX2 - SELECT product - This blocks until TX1 has been committed
TX1 - INSERT updated product
TX1 - COMMIT
TX2 - SELECT product - Error occurs here...
如果我使用事务级别 ReadCommitted,我会返回 0 行。请注意,TX2 是在 TX1 中删除产品之后创建的。
我无法使用 Serializable 或 RepeatableRead,因为行已更改,我得到 pq: could not serialize access due to concurrent update。
有没有办法让TX2 中的SELECT 阻塞直到TX1 完成,然后SELECT 新更新的行?我是否错误地使用了SELECT...FOR UPDATE?
【问题讨论】:
-
为什么不更新而不是删除和插入?
标签: sql postgresql concurrency transactions isolation-level