【发布时间】: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