有一段时间没有使用SAGA和spring-kafka
(和spring-cloud-stream-kafka-binder
)。
上下文:有几个(3+)Spring-boot
个微服务必须跨越业务交易,才能使数据保持最终一致的状态。他们使用Database-per-Service方法(每个服务将数据存储在Postgres中),并通过Kafka作为Event-Store进行协作。
我将应用SAGA(编排或编排方法,让我们坚持第一种方法)来管理多个服务上的事务。
问题是:当将RDBMS(Postgres)用作数据存储以及将Kafka用作事件存储/消息中间件时,如何支持本地事务?
[如今,spring-kafka实际上是否支持JTA事务,将RDBMS和Kafka Producer包装到@Transactional
方法中就足够了吗?还是我们仍然必须应用某些事务性微服务模式(例如Transactional Outbox,Transaction Log Tailing或Polling Publisher)?
提前感谢
Kafka不支持JTA / XA。您可以做的最好的就是“尽力而为1PC”-见Dave Syer's Javaworld article;您必须处理可能的重复项。
Apache Kafka的Spring提供了ChainedKafkaTransactionManager
;对于消费者发起的交易,应将CKTM注入侦听器容器。
CKTM应该首先拥有KTM,然后是RDBMS,因此将首先提交RDBMS事务;如果失败,则Kafka tx将回滚并重新传送记录。如果数据库成功但Kafka失败,则将重新传递记录(使用默认配置)。
对于仅限生产者的交易,您可以使用@Transactional
。在这种情况下,TM可以只是RDBMS TM,Spring-Kafka将同步本地Kafka事务,最后一次提交。