对于我的实现,必须批量完成特定的写操作,而不会有其他干扰。
我一直told以这种方式进行的两次竞争交易将导致第一次阻止第二次交易,而第二次交易可能会或者可能不会在第一次交易完成后完成。
请发布确认此文件的文件。另外,如果第一个事务阻塞,第二个事务究竟会发生什么?是排队,失败还是某种组合?
如果无法确认,此事务的事务隔离级别是否应设置为SERIALIZABLE
?如果是这样,如何用libpqxx预处理语句完成?
如果事务是序列化的,第二个事务是否会失败或排队,直到第一个事务完成?
如果其中一个失败,如何用libpqxx检测到它?
答案 0 :(得分:2)
最终阻止并发效应的唯一方法是LOCK TABLE ... IN ACCESS EXCLUSIVE MODE
每个要修改的表。
这意味着你一次只做一件事。如果你不总是以相同的顺序获得你的锁,那么它也会导致死锁的有趣问题。
通常,您需要做的是弄清楚您希望做的操作到底是什么,以及它们如何相互作用。确定您可以容忍的并发效果,以及如何防止那些您无法忍受的并发效果。
现在这个问题太宽泛而无法有效回答。
选项包括:
独家锁定表格。 (这是唯一的方法在PostgreSQL中立即执行多行upsert而没有并发问题)。请注意锁升级和锁定顺序相关的死锁。
正确使用SERIALIZABLE
隔离 - 但请记住,您必须能够记录您在交易期间所做的事情,并在tx中止时重试。
谨慎的行级锁定 - SELECT ... FOR UPDATE
,SELECT ... FOR SHARE
。
"乐观锁定" /乐观并发控制,适当时
以使其对并发操作更友好的方式编写查询。例如,用就地更新替换读 - 修改 - 写周期。