【问题标题】:Distributed transaction with 2 phase commit - atomicity issue due to commit phase not being synchronous具有 2 阶段提交的分布式事务 - 由于提交阶段不同步导致的原子性问题
【发布时间】:2019-11-03 23:04:30
【问题描述】:

我有一个 WCF 服务,其中包含一个标有 OperationBehavior(TransactionScopeRequired=true)TransactionFlow(TransactionFlowOption.Allowed) 的操作。

这个服务的客户端也是事务的一部分(它也有一个数据库。这是一个简化的例子),所以这涉及到分布式事务和两阶段提交。

为了让我的数据库操作支持两阶段提交,我实现了 IEnlistmentNotification 接口。
在准备阶段,我将数据写入带有事务标签的数据库,在提交阶段,我从数据中删除事务标签。请注意,提交阶段包括数据库访问,因此可能会有点慢。

问题在于,从看起来和我读到的内容来看,提交阶段是异步运行的,因此例如,以下 sequential 场景可能不起作用:

1) 事务 1:客户端插入 A
2)事务2:客户端插入依赖于A的B(服务器查找A,从中提取信息并使用它插入B)

由于事务 1 的提交阶段可能尚未在服务器端完成,事务 2 可能找不到 A(因为它仍然标记有“事务 1”标签)。
这两个事务可能会一个接一个地快速发生,所以这是一个竞争条件的问题。
我注意到它的方式是当我启用我的数据库驱动程序的日志记录时,提交变得有点慢,并且在第二个事务上发生了错误。如果我禁用了日志记录,那么它就成功了。但即使我禁用了日志记录,这仍然是竞争条件的问题,我不会在生产环境中依赖它。

解决这个问题的最佳方法是什么?

【问题讨论】:

  • 你必须使用 2 阶段提交吗?也许使用 SAGA 的方法更好?
  • 是的,请假设需要 2 阶段提交。如前所述,这是对系统的简化描述。这是一个已经可以与 2PC 配合使用的现有系统。事实上,有多个服务器是并行触发的。到目前为止,每个服务器都有一个 SQL Server 实例(支持开箱即用的 2PC),现在我们正在将一些服务器的 DB 替换为需要手动集成 2PC 的不同 DB。带有 SQL Server 的那些正在生产中,无法更改。所以从产品的角度来看,此时改变交易机制是不可能的。

标签: c# wcf transactions atomic 2phase-commit


【解决方案1】:

我已经遇到过这个问题,我们通过精心策划的传奇来解决这个问题。实现它所需要的只是一个消息队列(apache kafka、rabbit MQ ...)。然后每个客户端必须发送一个简单的数据作为执行事件的通知,例如{"event": "projectAdded"...}.
您需要一个协调员来订阅该事件并将新事件发送给下一个客户,例如{"event": "sendNotification"..},后者将收听该事件以开始工作。
为了一致性,您甚至可以发送一些事件,如{"error": "projectAdditionFailed"...},以便回滚和补偿执行的事件

【讨论】:

    猜你喜欢
    • 2012-07-20
    • 2015-12-30
    • 2013-12-07
    • 2014-03-16
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 2011-11-15
    • 2012-06-27
    相关资源
    最近更新 更多