如何创建事务';包装器';用于多种服务

本文关键字:用于 服务 包装 何创建 创建 事务 | 更新日期: 2023-09-27 17:59:04

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

为了更清晰的图片,我给你举个例子:

我得到了服务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     
    }

如有任何帮助,我们将不胜感激:)

如何创建事务';包装器';用于多种服务

目前我正在使用TransactionScope来"包装"事务,但是不起作用

在事务作用域中封装对物理外部资源的调用只能在非常精确配置的条件下工作(有些人会说人为)。

在您的示例中(假设服务和数据库位于彼此和调用方不同的物理主机上),您将从调用方主机到服务主机,跨越服务边界,到数据库主机,再进入数据库,再回到服务主机,再回到服务边界,再回到调用方主机。

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

为了做到这一点:

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

因此,除非所有这些都完成了,否则在这种情况下,您连续进行两个服务调用的事实没有什么不同。单个服务调用将无法将事务向下传播到DB并再次传播回来。

即使您已经知道以上内容,并且已经完成了所有这些步骤,以便支持跨多个服务调用的分布式事务支持,我仍然不建议您这样做。事务处理成本高昂,并且鼓励共享对解决方案的环境依赖性。尤其是当您正在计划一种微服务风格的方法时。

更简单的做法是让每个服务公开一个恢复或回滚操作,这样调用方就可以采取适当的操作,并将之前进行的任何调用回滚到失败的调用。这种方法被称为补偿模式。

如果我正确地理解了你的描述,上面的代码看起来像是在第三服务中还是共享代码中?

在构建自主组件时,它们不应该共享资源或代码,因为这将违背松散耦合的基本思想。。。

(micro)服务A(组件A)应仅修改并拥有DB A中的数据B 也是如此

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

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

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

这有道理吗?