我有一个使用AMQ / Camel消费消息的后端应用程序。在每个消息处理期间,使用@Transactional
JDBC DAO完成数据库插入。我配置了两个消息代理。
问题:如果主代理停止,当前的交换在消费者中变得陈旧:其中一些已经进行了插入,但还没有向代理发回ACK。最后,代理将执行消息回滚,然后应用程序再次获取相同的消息,从而导致数据库错误,因为它们已经插入。
如何配置路由以便在连接断开时尝试回滚?这只有在我以编程方式管理交易时才有可能吗?
答案 0 :(得分:1)
首先,DAO上的@Transactional
没有意义。您希望在完成请求后提交到数据库。对于Web应用程序,您通常在控制器上具有事务边界。对于JMS使用者,您可以在消费者(或附近)使用它。这样,您的事务边界就包含您的业务逻辑以及持久逻辑。一旦线程通过事务边界,该边界的事务管理器将提交(至少在其管理一个资源时,如DB),并且在此之后无法回滚。
也就是说,使用多个数据源管理事务通常是一个难题。在大多数情况下,您可以更容易地使系统对重复的消息具有弹性,而不是将提交同步到多个数据源(例如,在开始处理新消息之前保留消息ID并查找它)。
你有一些选择:
.transacted()
为
第一条指令之一,或者您可以标记JMS
使用transacted=true
的消费者,然后挂钩事务
提交到数据库的管理器。您可能仍然在提交数据库时回滚代理,因此您需要一些逻辑来处理重复的消息。XA事务将是一个比处理重复消息更复杂的解决方案,它将需要更多的开发人员。你被警告了。