0

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

该服务的客户端也是事务的一部分(它也有一个数据库。这是一个简化的示例),因此这涉及分布式事务和 2-phase-commit。

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

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

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

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

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

4

1 回答 1

0

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

于 2019-10-31T12:36:39.793 回答