如何创建一个Transaction' Wrapper'多项服务?

时间:2016-07-28 07:03:34

标签: c# web-services wcf transactions microservices

目前,我正在开发一个以MicroServices为主要概念的项目。

为了更清晰的图片,我将举例说明:

我得到了 Service A ,它有自己的模型和控制器。

基本上,服务A仅包含数据库A 的基本CRUD操作。

其次,我得到服务B ,与服务A相同,但不同的数据库(数据库B )。

现在,我创建了1个服务来同时使用服务A和服务B.目前我正在使用TransactionScope来包装'交易,但它没有工作。

以下是代码:

//This is the service to call Service A and Service B
using (TransactionScope ts = new TransactionScope())
{
     callServiceAMethod(); // works good
     callServiceBMethod(); // something happened, and failed

     //from here I don't know what should I do
     //What I'm expecting is : if one of the service i just called didn't work as expected, 
     //the transaction will be rolled back else will committed     
    }

任何帮助将不胜感激:)

2 个答案:

答案 0 :(得分:2)

  

目前,我正在使用TransactionScope来包装'这笔交易,但是   它没有工作

在事务范围内包含对物理外部资源的调用只能在非常精确配置(有些人会说人为的)条件下工作。

在您的示例中(假设服务和数据库在彼此和调用者的不同物理主机上),您将从调用者主机,服务主机,跨服务边界,到数据库主机,进入数据库,退回到服务主机,返回服务边界,然后返回到主叫主机。

为了将分布式事务从客户端传播到数据库,调用链中每个步骤的每个中介都必须登记到事务中。

为了做到这一点:

  • 必须在每个参与主机上正确启用和配置MSDTC,
  • 必须使用支持WS-AtomicTransaction的绑定(如wsHttpBinding)和
  • 进行服务调用
  • 必须专门构建服务以支持交易行为。

因此,除非完成所有这些操作,否则连续进行两次服务调用的事实在这种情况下没有任何区别。单个服务调用将无法将事务传播到数据库并再次传回。

即使您已经了解上述内容并已完成所有这些步骤以支持跨多个服务调用的分布式事务支持,我仍然不建议您这样做。交易成本高昂,并鼓励共享环境依赖于解决方案。特别是在您计划微服务风格的方法时。

最简单的方法是让每个服务都公开恢复或回滚操作,这样调用者就可以采取适当的操作并回滚先前对失败的调用进行的任何调用。这种方法称为compensation pattern

答案 1 :(得分:2)

如果我的说明正确,看起来上面的代码是第3个服务还是共享代码?

在构建自治组件时,他们不应该共享资源或代码,因为这会破坏松耦合的基本思想......

(微)服务A(组件A)应该只修改和拥有DB A中的数据 和B

相同

一旦A完成了他的任务,它应该提出一个事件B订阅,B将处理该事件并完成他的工作。

如果其中任何一个失败,他们可以举起像xOperationFailed这样的事件(即CreatUserAccountFailed),订阅该事件的感兴趣的组件将根据业务逻辑采取行动(回滚,暂停,发送)向用户或管理员发送电子邮件以采取纠正措施)。成功也是如此(他们可以举办成功活动)。

困难的部分是定义每个组件的边界(职责和数据)......

这有意义吗?