微服务中的分布式事务管理

news/2024/12/27 16:33:51/文章来源:https://www.cnblogs.com/chenshibao/p/18636092

在微服务架构中,传统的两阶段提交和三阶段提交协议由于其性能开销和可用性问题,通常不被推荐使用。相反,微服务架构更倾向于使用其他分布式事务管理策略,如Saga模式、事件溯源(Event Sourcing)、补偿事务(Compensating Transactions)等,这些策略能够在保证数据一致性的同时,提供更好的性能和可用性。

  1. Saga模式
    Saga模式是一种处理分布式事务的长事务模式,通过一系列本地事务和补偿事务来确保全局事务的一致性。
  • 编排型Saga:
    • 使用一个协调器来管理整个Saga流程。
    • 协调器负责启动和管理各个本地事务,并在某个本地事务失败时触发相应的补偿事务。
  • 编排型Saga:
    • 每个服务都是Saga的参与者,并通过消息队列进行通信。
    • 服务在完成本地事务后发送消息通知其他服务。
    • 如果某个本地事务失败,服务发送补偿消息来回滚之前的事务。

示例:编排型Saga

	public class OrderService{private readonly IOrderRepository _orderRepository;private readonly IMessageBus _messageBus;public OrderService(IOrderRepository orderRepository, IMessageBus messageBus){_orderRepository = orderRepository;_messageBus = messageBus;}public void CreateOrder(OrderCreationDto orderDto){// 应用层逻辑:数据验证if (orderDto.Items == null || orderDto.Items.Count == 0){throw new ArgumentException("Order items are required.");}// 创建订单本地事务var order = new Order{UserId = orderDto.UserId,Items = orderDto.Items.Select(itemDto => new OrderItem{ProductId = itemDto.ProductId,Quantity = itemDto.Quantity}).ToList(),TotalAmount = orderDto.Items.Sum(itemDto => itemDto.Price * itemDto.Quantity)};_orderRepository.Add(order);// 发送订单创建事件var orderCreatedEvent = new OrderCreatedEvent { OrderId = order.Id, TotalAmount = order.TotalAmount };_messageBus.Publish(orderCreatedEvent);}public void RollbackOrder(long orderId){// 处理订单回滚逻辑var order = _orderRepository.GetById(orderId);if (order != null){_orderRepository.Delete(order);}}}public class PaymentService{private readonly IPaymentRepository _paymentRepository;private readonly IMessageBus _messageBus;public PaymentService(IPaymentRepository paymentRepository, IMessageBus messageBus){_paymentRepository = paymentRepository;_messageBus = messageBus;}public void HandleOrderCreatedEvent(OrderCreatedEvent @event){try{// 处理支付本地事务ProcessPayment(@event.OrderId, @event.TotalAmount);// 发送支付成功事件var paymentSuccessEvent = new PaymentSuccessEvent { OrderId = @event.OrderId };_messageBus.Publish(paymentSuccessEvent);}catch (Exception ex){// 发送支付失败事件var paymentFailureEvent = new PaymentFailureEvent { OrderId = @event.OrderId };_messageBus.Publish(paymentFailureEvent);}}private void ProcessPayment(long orderId, decimal amount){// 处理支付逻辑}public void RollbackPayment(long orderId){// 处理支付回滚逻辑_paymentRepository.Rollback(orderId);}}public class InventoryService{private readonly IInventoryRepository _inventoryRepository;private readonly IMessageBus _messageBus;public InventoryService(IInventoryRepository inventoryRepository, IMessageBus messageBus){_inventoryRepository = inventoryRepository;_messageBus = messageBus;}public void HandlePaymentSuccessEvent(PaymentSuccessEvent @event){try{// 处理库存本地事务UpdateInventory(@event.OrderId);// 发送库存更新成功事件var inventorySuccessEvent = new InventorySuccessEvent { OrderId = @event.OrderId };_messageBus.Publish(inventorySuccessEvent);}catch (Exception ex){// 发送库存更新失败事件var inventoryFailureEvent = new InventoryFailureEvent { OrderId = @event.OrderId };_messageBus.Publish(inventoryFailureEvent);}}private void UpdateInventory(long orderId){// 更新库存逻辑}public void RollbackInventory(long orderId){// 处理库存回滚逻辑_inventoryRepository.Rollback(orderId);}}
  1. 事件溯源(Event Sourcing)
    事件溯源是一种记录系统状态变化的方式,通过记录系统中的每个事件来重建系统状态。
  • 事件记录:
    • 每个操作都被记录为一个事件。
  • 事件处理:
    • 事件被处理以更新系统的状态。
  • 补偿机制:
    • 如果某个事件处理失败,可以通过记录的事件来恢复系统的状态。

示例:事件溯源

	public class EventSourcingExample{private readonly IEventStore _eventStore;public EventSourcingExample(IEventStore eventStore){_eventStore = eventStore;}public void CreateOrder(OrderCreationDto orderDto){// 应用层逻辑:数据验证if (orderDto.Items == null || orderDto.Items.Count == 0){throw new ArgumentException("Order items are required.");}// 创建订单事件var orderCreatedEvent = new OrderCreatedEvent{OrderId = orderDto.UserId,Items = orderDto.Items.Select(itemDto => new OrderItem{ProductId = itemDto.ProductId,Quantity = itemDto.Quantity}).ToList(),TotalAmount = orderDto.Items.Sum(itemDto => itemDto.Price * itemDto.Quantity)};// 保存事件_eventStore.Save(orderCreatedEvent);// 处理订单事件var order = new Order(orderCreatedEvent);ProcessOrder(order);}private void ProcessOrder(Order order){// 处理订单逻辑}public void RollbackOrder(long orderId){// 回滚订单逻辑var order = _eventStore.Load<OrderCreatedEvent>(orderId);if (order != null){RollbackOrder(order);}}}
  1. 补偿事务(Compensating Transactions)

补偿事务是一种通过记录补偿操作来处理分布式事务回滚的方式。当某个本地事务失败时,通过执行相应的补偿事务来回滚之前的操作。

示例:补偿事务

	public class CompensatingTransactionExample{private readonly IOrderRepository _orderRepository;private readonly IPaymentRepository _paymentRepository;private readonly IInventoryRepository _inventoryRepository;public CompensatingTransactionExample(IOrderRepository orderRepository, IPaymentRepository paymentRepository, IInventoryRepository inventoryRepository){_orderRepository = orderRepository;_paymentRepository = paymentRepository;_inventoryRepository = inventoryRepository;}public void CreateOrder(OrderCreationDto orderDto){// 应用层逻辑:数据验证if (orderDto.Items == null || orderDto.Items.Count == 0){throw new ArgumentException("Order items are required.");}// 创建订单本地事务var order = new Order{UserId = orderDto.UserId,Items = orderDto.Items.Select(itemDto => new OrderItem{ProductId = itemDto.ProductId,Quantity = itemDto.Quantity}).ToList(),TotalAmount = orderDto.Items.Sum(itemDto => itemDto.Price * itemDto.Quantity)};try{// 保存订单_orderRepository.Add(order);// 处理支付本地事务ProcessPayment(order.Id, order.TotalAmount);// 处理库存本地事务UpdateInventory(order.Id);}catch (Exception ex){// 回滚订单_orderRepository.Delete(order);// 回滚支付_paymentRepository.Rollback(order.Id);// 回滚库存_inventoryRepository.Rollback(order.Id);throw new InvalidOperationException("Order creation failed.");}}private void ProcessPayment(long orderId, decimal amount){// 处理支付逻辑}private void UpdateInventory(long orderId){// 更新库存逻辑}}

总结

  • 一阶段提交(One-Phase Commit):
    • 简单但缺乏一致性和可用性。
    • 不适用于复杂的分布式事务。
  • 两阶段提交(Two-Phase Commit, 2PC):
    • 通过准备和提交阶段确保一致性。
    • 性能开销大,可用性较低。
    • 不适用于高可用性要求的微服务架构。
  • 三阶段提交(Three-Phase Commit, 3PC):
    • 增加了投票阶段来处理参与者故障。
    • 性能开销更大,复杂性更高。
    • 仍然不适用于高可用性要求的微服务架构。

微服务中的推荐策略

在微服务架构中,推荐使用以下策略来管理分布式事务:

  1. Saga模式:

    • 通过一系列本地事务和补偿事务来确保全局事务的一致性。
    • 支持编排型和编排型两种方式。
    • 提供更好的性能和可用性。
  2. 事件溯源(Event Sourcing):

    • 记录系统中的每个事件,通过事件重建系统状态。
    • 提供强大的回滚和恢复机制。
  3. 补偿事务(Compensating Transactions):

    • 记录补偿操作,当某个本地事务失败时执行补偿事务来回滚操作。
    • 提供简单的回滚机制。

通过使用这些现代的分布式事务管理策略,可以在保证数据一致性的同时,提高微服务架构的性能和可用性。

示例:结合Saga模式和补偿事务
假设我们继续使用电子商务平台的示例,结合Saga模式和补偿事务来管理订单创建的分布式事务。

	public class OrderService{private readonly IOrderRepository _orderRepository;private readonly IMessageBus _messageBus;public OrderService(IOrderRepository orderRepository, IMessageBus messageBus){_orderRepository = orderRepository;_messageBus = messageBus;}public void CreateOrder(OrderCreationDto orderDto){// 应用层逻辑:数据验证if (orderDto.Items == null || orderDto.Items.Count == 0){throw new ArgumentException("Order items are required.");}// 创建订单本地事务var order = new Order{UserId = orderDto.UserId,Items = orderDto.Items.Select(itemDto => new OrderItem{ProductId = itemDto.ProductId,Quantity = itemDto.Quantity}).ToList(),TotalAmount = orderDto.Items.Sum(itemDto => itemDto.Price * itemDto.Quantity)};_orderRepository.Add(order);// 发送订单创建事件var orderCreatedEvent = new OrderCreatedEvent { OrderId = order.Id, TotalAmount = order.TotalAmount };_messageBus.Publish(orderCreatedEvent);}public void RollbackOrder(long orderId){// 处理订单回滚逻辑var order = _orderRepository.GetById(orderId);if (order != null){_orderRepository.Delete(order);// 发送订单回滚事件var orderRollbackEvent = new OrderRollbackEvent { OrderId = orderId };_messageBus.Publish(orderRollbackEvent);}}}public class PaymentService{private readonly IPaymentRepository _paymentRepository;private readonly IMessageBus _messageBus;public PaymentService(IPaymentRepository paymentRepository, IMessageBus messageBus){_paymentRepository = paymentRepository;_messageBus = messageBus;}public void HandleOrderCreatedEvent(OrderCreatedEvent @event){try{// 处理支付本地事务ProcessPayment(@event.OrderId, @event.TotalAmount);// 发送支付成功事件var paymentSuccessEvent = new PaymentSuccessEvent { OrderId = @event.OrderId };_messageBus.Publish(paymentSuccessEvent);}catch (Exception ex){// 发送支付失败事件var paymentFailureEvent = new PaymentFailureEvent { OrderId = @event.OrderId };_messageBus.Publish(paymentFailureEvent);}}private void ProcessPayment(long orderId, decimal amount){// 处理支付逻辑}public void RollbackPayment(long orderId){// 处理支付回滚逻辑_paymentRepository.Rollback(orderId);// 发送支付回滚事件var paymentRollbackEvent = new PaymentRollbackEvent { OrderId = orderId };_messageBus.Publish(paymentRollbackEvent);}}public class InventoryService{private readonly IInventoryRepository _inventoryRepository;private readonly IMessageBus _messageBus;public InventoryService(IInventoryRepository inventoryRepository, IMessageBus messageBus){_inventoryRepository = inventoryRepository;_messageBus = messageBus;}public void HandlePaymentSuccessEvent(PaymentSuccessEvent @event){try{// 处理库存本地事务UpdateInventory(@event.OrderId);// 发送库存更新成功事件var inventorySuccessEvent = new InventorySuccessEvent { OrderId = @event.OrderId };_messageBus.Publish(inventorySuccessEvent);}catch (Exception ex){// 发送库存更新失败事件var inventoryFailureEvent = new InventoryFailureEvent { OrderId = @event.OrderId };_messageBus.Publish(inventoryFailureEvent);}}private void UpdateInventory(long orderId){// 更新库存逻辑}public void RollbackInventory(long orderId){// 处理库存回滚逻辑_inventoryRepository.Rollback(orderId);// 发送库存回滚事件var inventoryRollbackEvent = new InventoryRollbackEvent { OrderId = orderId };_messageBus.Publish(inventoryRollbackEvent);}}public class Program{public static void Main(){var orderRepository = new OrderRepository();var paymentRepository = new PaymentRepository();var inventoryRepository = new InventoryRepository();var messageBus = new MessageBus();var orderService = new OrderService(orderRepository, messageBus);var paymentService = new PaymentService(paymentRepository, messageBus);var inventoryService = new InventoryService(inventoryRepository, messageBus);messageBus.Subscribe<OrderCreatedEvent>(paymentService.HandleOrderCreatedEvent);messageBus.Subscribe<PaymentSuccessEvent>(inventoryService.HandlePaymentSuccessEvent);messageBus.Subscribe<PaymentFailureEvent>(orderService.RollbackOrder);messageBus.Subscribe<InventoryFailureEvent>(paymentService.RollbackPayment);messageBus.Subscribe<PaymentRollbackEvent>(orderService.RollbackOrder);messageBus.Subscribe<InventoryRollbackEvent>(inventoryService.RollbackInventory);// 创建订单var orderDto = new OrderCreationDto{UserId = 123,Items = new List<OrderItemDto>{new OrderItemDto { ProductId = 456, Quantity = 2, Price = 10.0m }}};orderService.CreateOrder(orderDto);}}

关键点

  1. 事件驱动:
    使用事件驱动的方式来协调各个服务之间的操作。
  2. 补偿机制:
    在某个服务失败时,通过补偿机制来回滚之前的操作。
  3. 消息队列:
    使用消息队列来处理事件的传递,确保消息的可靠性和顺序。
  4. 幂等性:
    确保处理事件的方法是幂等的,即多次执行相同的操作不会导致不一致的结果。
    通过这些现代的分布式事务管理策略,微服务架构能够在保证数据一致性的同时,提高系统的灵活性和可维护性。

总结

  • 一阶段提交(One-Phase Commit):
    • 简单但缺乏一致性和可用性。
    • 适用于非常简单的场景,但不适合复杂的分布式事务。
  • 两阶段提交(Two-Phase Commit, 2PC):
    • 通过准备和提交阶段确保一致性。
    • 性能开销大,可用性较低。
    • 不适用于高可用性要求的微服务架构。
  • 三阶段提交(Three-Phase Commit, 3PC):
    • 增加了投票阶段来处理参与者故障。
    • 性能开销更大,复杂性更高。
    • 仍然不适用于高可用性要求的微服务架构。

推荐策略

在微服务架构中,推荐使用以下策略来管理分布式事务:

  1. Saga模式:
    • 通过一系列本地事务和补偿事务来确保全局事务的一致性。
    • 支持编排型和编排型两种方式。
    • 提供更好的性能和可用性。
  2. 事件溯源(Event Sourcing):
    • 记录系统中的每个事件,通过事件重建系统状态。
    • 提供强大的回滚和恢复机制。
  3. 补偿事务(Compensating Transactions):
    • 记录补偿操作,当某个本地事务失败时执行补偿事务来回滚操作。
    • 提供简单的回滚机制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/859902.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DL00768-基于YOLO深度学习的电瓶车佩戴头盔检测系统python实现

DL00768-基于YOLO深度学习的电瓶车佩戴头盔检测系统python实现 可支持发票随着城市交通拥堵问题的加剧和共享电动车的普及,电动车安全问题引起了广泛关注,尤其是骑行者佩戴头盔的问题。佩戴头盔是确保骑行安全的关键措施,但由于部分骑行者未按规定佩戴头盔,导致了大量交通事…

vs code 合并分支,界面操作

简单描述: 如其他分支合并到dev 里面,切换到dev分支,然后用终端 git pull 一下,再“分支”--"合并" 选择要合并的其他分支,最后推送 界面如下: 点击切换分支,git pull 选择要合并的其他分支,合并 点击“合并”后,弹出分支后,选择要合并的分支,如feature_…

GO 学习笔记之零 (三)常见问题处理集锦

1、Golang如何解决case-insensitive import collision问题 1.1 现象1.2 解决方法该问题产生说明在所有go文件中引入包时,存在 ShipModel/Radar 和 ShipModel/radar 两种写法,需要统一。对于VSCODE工具,可以在 全局文件中搜索 ShipModel/Radar 查看 写法是不是一样,然后 进行…

UML之属性与参数的多重性

在UML中,多重性是指一个条目潜在的数量范围。多重性可被用于属性、操作参数、关联关系。UML元模型也使用多重性对元模型元素之间的关系进行约束。多重性总是包含基数值,它是相关条目在现实世界中的确切数量。本文将说明类属性和类操作参数的多重性。 一、属性的多重性 假设我…

水仓水位异常识别智慧矿山一体机构建智慧矿山系统:监控硬盘如何影响监控系统的稳定性?

中国作为全球最大的煤炭生产和消费国,煤矿行业在能源供应中依然占据重要地位。虽然国家逐步推动能源结构转型,发展可再生能源,但煤炭仍然在短期内满足能源需求方面发挥着重要作用。近年来,煤矿安全生产水平有所提高,但仍存在一定的安全隐患。国家对煤矿的安全监管力度加大…

FANUC发那科机器人控制箱维修操作流程

FANUC发那科机器人在工业自动化领域中占有重要地位,其高效、稳定和精确的性能赢得了众多用户的青睐。然而,随着使用时间的增长,可能会出现FANUC机器人控制柜故障,影响到发那科机器人的正常运行。本文将详细介绍发那科FANUC机器人控制箱维修操作流程,帮助企业更好地了解和掌…

CH592 memcpy

memcpy提速方法: #define ALIGN_MASK 0x3 #define COPY32 *d32 = *s32; d32++; s32++; #define COPY8 *d8 = *s8; d8++; s8++; #define SET32(x) *d32 = x; d32++; #define SET8(x) *d8 = x; d8++; #define REPEAT8(expr) expr expr expr expr expr expr expr expr type…

【工作相关】gki boot.img下载

地址 https://source.android.com/docs/core/architecture/kernel/gki-android13-5_15-release-builds?hl=zh-cn Android13-5.15 发布版本查看Linux version信息: 相关解包命令参考这里【传送门】 解包过程:~/cts/gki$ ../bin/unpack_bootimg --boot_img boot-5.15.img --ou…

鸿蒙NEXT开发实战教程—小红书app

幽蓝君最近发现小红书是个好东西,一定要多逛今天就浅浅模仿一下小红书app,主要是底部tab栏和主页部分。首先看一下tabbar,由于中间有一个红色按钮的存在,所以这里我使用自定义导航栏来实现,自定义的实现逻辑是在本来app的上层叠加一层自定义tabbar,使用监听index的变化来…

Python数据结构之双向循环链表

1、循环双向链表特点通过当前结点直接获取上一结点 通过头结点的上一结点直接可以去找到尾结点 可以进行反向循环链表,即反转链表2、头结点 链表头: 在数据结构中,链表是一种常见的存储结构。链表的每个节点包含数据和指向下一个节点的指针。链表头是链表的第一个节点,它在…

CDS标准视图:功能位置 I_FunctionalLocation

视图名称:I_FunctionalLocation 视图类型:基础 视图代码:点击查看代码 @EndUserText.label: Functional Location @Analytics: { dataCategory: #DIMENSION } @VDM.viewType: #BASIC @AbapCatalog: { sqlViewName: IFUNCTLLOCATION, compiler.compareFilter, preserveKey } …

DNS 原理入门

DNS 原理入门 导读 DNS 是互联网核心协议之一。不管是上网浏览,还是编程开发,都需要了解一点它的知识。本文详细介绍DNS的原理,以及如何运用工具软件观察它的运作。我的目标是,读完此文后,你就能完全理解DNS。一、DNS 是什么? DNS (Domain Name System 的缩写)的作用非…