对于我的实现,特定的写入必须批量完成,并且没有其他干扰的机会。

我已经 告诉 以这种方式进行的两个竞争事务将导致第一个事务阻塞第二个事务,并且第二个事务可能会在第一个事务完成后完成,也可能不会完成。

请发布确认这一点的文档。另外,如果第一个事务阻塞,第二个事务到底会发生什么?它会排队、失败还是某种组合?

如果无法确认这一点,是否应该将该事务的事务隔离级别设置为 SERIALIZABLE?如果是这样,如何使用 libpqxx 准备好的语句来完成此操作?

如果事务被序列化,第二个事务会失败还是会排队直到第一个事务完成?

如果其中一个失败,如何使用 libpqxx 检测到这一点?

有帮助吗?

解决方案

最终防止并发影响的唯一方法是 LOCK TABLE ... IN ACCESS EXCLUSIVE MODE 您想要修改的每个表。

这意味着你一次实际上只做一件事。如果您不总是以相同的顺序获取锁,它还会导致有趣的死锁问题。

因此,通常,您需要做的是弄清楚您想要执行的操作到底是什么,以及它们如何交互。确定您可以容忍哪些并发影响,以及如何防止您不能容忍的并发影响。

这个问题目前的范围太宽泛,无法有效回答。

选项包括:

  • 独占锁定表。(这是 唯一办法 现在在 PostgreSQL 中进行多行更新插入而不会出现并发问题)。注意锁升级和锁顺序相关的死锁。

  • 适当使用 SERIALIZABLE 隔离 - 但请记住,您必须能够记录事务期间所做的事情,并在事务中止时重试。

  • 小心行级锁定 - SELECT ... FOR UPDATE, SELECT ... FOR SHARE.

  • “乐观锁定”/乐观并发控制(如果适用)

  • 以更适合并发操作的方式编写查询。例如,用就地更新替换读取-修改-写入周期。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top