【问题标题】:libpqxx transaction serialization & consequenceslibpqxx 事务序列化和后果
【发布时间】:2014-04-13 18:25:56
【问题描述】:

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

我一直told 认为,这样的两个竞争事务会导致第一个阻塞第二个,第二个可能会在第一个完成后完成,也可能不会完成。

请张贴证实这一点的文件。此外,如果第一个事务阻塞,第二个事务究竟会发生什么?它会排队、失败还是某种组合?

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

如果事务是序列化的,第二个事务会失败还是排队等待第一个事务完成?

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

【问题讨论】:

  • 您对“干扰”的定义是什么?
  • 写入的性质是什么?插入新记录?更新现有记录?删除记录?更新,如果不存在插入(即 upsert)?

标签: c++ postgresql serialization transaction-isolation libpqxx


【解决方案1】:

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

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

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

这个问题太宽泛了,无法有效回答。

选项包括:

  • 独占锁定表。 (这是目前在 PostgreSQL 中进行多行 upsert 而没有并发问题的唯一方法)。当心锁升级和锁顺序相关的死锁。

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

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

  • “乐观锁定”/乐观并发控制(在适当的情况下)

  • 以使查询对并发操作更友好的方式编写查询。例如,用就地更新替换读-修改-写周期。

【讨论】:

  • 我无法清楚地理解您所说的“干涉”是什么意思,所以很难准确地说出这一切是什么意思。你需要更具体一点。根据您在 cmets 中的描述,我会说这是 You're Doing It Wrong™ 的情况,即“如果我不使用序列,可能会发生这些坏事,我该怎么办?”。 使用序列.
  • 由于我无法准确猜出您的意思,因此我无法确定您对丹尼尔所说内容的解释是否与我的相同,以及他是否正确。丹尼尔知道他的东西,而且很少出错,但整个讨论令人困惑,很难说出它意味着什么。看,您是在针对一个宽泛、一般、挥手致意的问题要求具体答案。这不是它的工作原理。给我一个具体的问题,我给你一个具体的答案。您对预期工作量的描述绝非具体。
猜你喜欢
  • 2015-01-17
  • 1970-01-01
  • 2012-07-18
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 2014-11-22
  • 2010-11-26
  • 1970-01-01
相关资源
最近更新 更多