神秘的传奇在c#设计模式:治愈分布式事务问题
世界上的分布式系统,跨不同的服务通常可以管理事务带来了重大的挑战。传统方法二段式提交和三相提交模式已经在独立应用程序可靠的同伴,但他们缺乏现代时,分布式环境。本文还探讨了传奇设计模式,一种强大的方法,在分布式环境中解决这些问题。我们将深入研究它的定义、类型和补偿的概念,以一个真实的电子商务平台的例子。
手边的问题
当涉及到交易在整体架构中,典型的方法是ACID(原子性、一致性、隔离、耐久性)模型,通过二段式或三相提交与分布式事务执行模式。然而,这些模型在分布式系统的可伸缩性和性能问题。
在microservices、事务可能跨多个服务,每一方都有自己的数据库。实施酸原则在这样一个背景下介绍了服务之间的紧密耦合,导致整个系统脆弱。更是如此,这是一个艰巨的任务维护全局事务锁在分布式系统中,导致明显的延迟。
进入故事模式
传奇设计模式成为解决这些问题。传奇是本地事务的序列,每个事务更新数据在一个服务。本地事务的失败引发了传奇的补偿机制,将执行补偿事务撤销之前的本地事务的影响。
传奇模式的主要优势是,它可以确保数据一致性跨多个服务和数据库没有锁定资源,从而消除固有的延迟问题,传统的分布式事务。
事件类型:编排和编制
传说主要有两种类型:编排和编制。
编排:在编排,每个本地事务发布一个事件在成功。其他本地事务订阅这些事件和条件得到满足时执行。虽然这种方法减少集中协调的需要,它可以是复杂的理解和监测由于其分布式特性。
编制:在编排中,有一个中心协调者(通常被称为一个协调器),告诉其他服务来执行本地事务。这种方法更容易理解和管理,因为执行逻辑的故事就是在一个地方。然而,它也可以成为瓶颈和单点故障如果设计不当。
补偿和电子商务的例子
传奇模式的一个独特的方面是它的补偿机制,取消一个交易事件的后续事务失败时。让我们用一个电子商务平台的例子加以说明。
考虑一个典型的购买传奇:
- 用户订单的地方。
- 付款处理。
- 订单确认和发货。
在c#中,每一个步骤可能是由不同的服务:
在这个模型中,每一步的传奇是一个命令操作通过一个特定处理器,它提供了执行
和补偿
方法。
下面是一个例子。net这样一个传奇模式的电子商务应用程序:
公共接口ICommandHandler
{
任务< bool > Execute ();
任务补偿();
}
/ /为PlaceOrder指挥和处理程序
公开课PlaceOrderCommand
{
公共秩序秩序{得到;设置;}
}
公开课PlaceOrderCommandHandler: ICommandHandler
{
公共异步任务< bool >执行(PlaceOrderCommand命令)
{
/ /逻辑顺序
/ /如果成功,返回true
/ /如果不是,返回false
}
公共异步任务< bool >补偿(PlaceOrderCommand命令)
{
/ /逻辑来取消订单
/ /如果成功,返回true
/ /如果不是,返回false
}
}
/ /为ProcessPayment指挥和处理程序
公开课ProcessPaymentCommand
{
公共支付支付{;设置;}
}
公开课ProcessPaymentCommandHandler: ICommandHandler
{
公共异步任务< bool >执行(ProcessPaymentCommand命令)
{
/ /逻辑来处理付款
/ /如果成功,返回true
/ /如果不是,返回false
}
公共异步任务< bool >补偿(ProcessPaymentCommand命令)
{
/ /逻辑退还货款
/ /如果成功,返回true
/ /如果不是,返回false
}
}
/ /为ConfirmAndShipOrder指挥和处理程序
公开课ConfirmAndShipOrderCommand
{
公共秩序秩序{得到;设置;}
}
公开课ConfirmAndShipOrderCommandHandler: ICommandHandler
{
公共异步任务< bool >执行(ConfirmAndShipOrderCommand命令)
{
/ /逻辑来确认和船订单
/ /如果成功,返回true
/ /如果不是,返回false
}
公共异步任务< bool >补偿(ConfirmAndShipOrderCommand命令)
{
/ /逻辑取消货物,恢复为初始状态
/ /如果成功,返回true
/ /如果不是,返回false
}
}
和Orchestratave传奇类
公开课PurchaseSaga
{
私有队列< ICommandHandler > _handlerQueue;
私人堆栈< ICommandHandler > _completedHandlers;
公共PurchaseSaga (
PlaceOrderCommandHandler placeOrderHandler,
ProcessPaymentCommandHandler paymentHandler,
ConfirmAndShipOrderCommandHandler shippingHandler)
{
_handlerQueue =新队列< ICommandHandler > ();
_completedHandlers = new堆栈< ICommandHandler > ();
_handlerQueue.Enqueue (placeOrderHandler);
_handlerQueue.Enqueue (paymentHandler);
_handlerQueue.Enqueue (shippingHandler);
}
公共异步任务执行()
{
而(_handlerQueue。数> 0)
{
var处理程序= _handlerQueue.Dequeue ();
如果等待handler.Execute ())
{
_completedHandlers.Push(处理器);
}
其他的
{
等待赔偿();
返回;
}
}
}
私人异步任务补偿()
{
而(_completedHandlers。数> 0)
{
var处理程序= _completedHandlers.Pop ();
等待handler.Compensate ();
}
}
}
在这个版本中,PurchaseSaga
维护一个队列的ICommandHandler
实例执行,和一堆ICommandHandler
实例已经完成。每一个ICommandHandler
接口有两个方法:执行
和补偿
。
的执行
个方法从队列处理程序并执行,推动成功的处理程序压入堆栈。如果一个处理程序不能执行补偿
方法被调用时,它会从堆栈,调用处理程序补偿
方法。
这种方法跟踪什么已经完成,需要撤销,如果传奇无法完成,提高代码的清晰性和可维护性。
结束
传奇设计模式提供了一个强大的替代传统的事务模型在分布式系统领域。所包含的本地事务和一个健壮的补偿机制,传奇支持构建可伸缩的、一致的、和弹性系统在面对失败。而理解和实施传奇需要相当程度的照顾,他们的利益复杂,分布式应用程序是毋庸置疑的。