我想在Spring Boot Microservices中使用SAGA模式。例如,按照客户的订单,在创建订单时,会产生类似OrderCreatedEvent
的事件,然后在客户微服务中,OrderCreatedEvent
上的监听器会更新客户信用并产生CreditUpdateEvent
和...。
我将事务处理的会话JmsTemplate
用于事件产生。在JmsTemplate
的javadoc中,JMS事务在主事务之后提交:
这具有与本地事务(可以是本地JDBC事务)一起管理本地JMS事务的效果,并且JMS事务在主要事务之后立即提交。
现在,我的问题是如何处理以下情况:
已提交主要事务(例如,已重新提交订单的订单),并且系统由于某种原因无法提交JMS事务。
我想使用SAGA而不是两阶段提交,但我认为只是SAGA将问题从订单和客户服务转移到订单服务和JMS提供者。
答案 0 :(得分:1)
SAGA提示了该问题:
还需要解决以下问题:
...
- 为了可靠,服务必须自动更新其数据库 并发布事件。它不能使用跨越数据库和消息代理的分布式事务的传统机制。相反,它必须使用下面列出的模式之一。
...
以下模式是自动更新状态和发布事件的方法:
- 活动来源
- 应用程序事件
- 数据库触发器
- 事务日志拖尾
Event Sourcing在此列表中很特殊,因为它对系统存储和处理数据的方式带来了根本性的变化。通常,系统仅存储实体的当前状态。一些系统为具有有效期和/或bitemporal data的历史状态添加了显式支持。
基于事件源的系统以允许其从事件中重构状态的方式存储事件序列而不是实体状态。只需维护一种事务处理资源-事件存储-因此无需协调事务处理。
列表中的其他模式通过要求事件生产者代码将所有更改(实体状态和事件(作为实体))提交到单个数据存储,从而避免了事务协调的问题。然后实施一种专用但独立的机制-事件发布者-从数据存储中获取事件并将其发布给事件使用者。
事件发布者需要跟踪已发布/未发布的事件,这通常会带来协调事务的问题。这就是消费者发现事件的幂等性。事件发布者将从上一个已知位置重播事件,而消费者将忽略重复事件。
您还可以撤消事件产生者和事件使用者的主动/被动方面。事件生产者将实体状态和事件(作为实体)存储到单个数据存储中,并提供一个端点,该端点允许事件使用者访问事件流。每个事件使用者都跟踪已处理/未处理的事件(出于幂等原因无论如何都需要这样做),但仅跟踪其感兴趣的事件流。 REST in Practice-第7章和第8章对这种方法进行了很好的解释。
答案 1 :(得分:0)
使用SAGA,您希望分三个阶段对交易(tx)步骤进行拆分或重新排序:
SAGA不是ACID,只有ACD。您需要实现自己的隔离,以防止脏读。通常带锁。
为什么要使用SAGA?为了避免运行时同步耦合和倒空可用性。您等待最后一位参与者提交。
要付出很高的代价。
机会很小,但您最终仍可能会遇到不一致的事件,这些事件可能会被用于获取汇总。