libpqxx 事务序列化和后果
-
21-12-2019 - |
题
对于我的实现,特定的写入必须批量完成,并且没有其他干扰的机会。
我已经 告诉 以这种方式进行的两个竞争事务将导致第一个事务阻塞第二个事务,并且第二个事务可能会在第一个事务完成后完成,也可能不会完成。
请发布确认这一点的文档。另外,如果第一个事务阻塞,第二个事务到底会发生什么?它会排队、失败还是某种组合?
如果无法确认这一点,是否应该将该事务的事务隔离级别设置为 SERIALIZABLE
?如果是这样,如何使用 libpqxx 准备好的语句来完成此操作?
如果事务被序列化,第二个事务会失败还是会排队直到第一个事务完成?
如果其中一个失败,如何使用 libpqxx 检测到这一点?
解决方案
最终防止并发影响的唯一方法是 LOCK TABLE ... IN ACCESS EXCLUSIVE MODE
您想要修改的每个表。
这意味着你一次实际上只做一件事。如果您不总是以相同的顺序获取锁,它还会导致有趣的死锁问题。
因此,通常,您需要做的是弄清楚您想要执行的操作到底是什么,以及它们如何交互。确定您可以容忍哪些并发影响,以及如何防止您不能容忍的并发影响。
这个问题目前的范围太宽泛,无法有效回答。
选项包括:
独占锁定表。(这是 唯一办法 现在在 PostgreSQL 中进行多行更新插入而不会出现并发问题)。注意锁升级和锁顺序相关的死锁。
适当使用
SERIALIZABLE
隔离 - 但请记住,您必须能够记录事务期间所做的事情,并在事务中止时重试。小心行级锁定 -
SELECT ... FOR UPDATE
,SELECT ... FOR SHARE
.“乐观锁定”/乐观并发控制(如果适用)
以更适合并发操作的方式编写查询。例如,用就地更新替换读取-修改-写入周期。
不隶属于 StackOverflow