我的路线如下所示
from("jms:queue:IN_QUEUE) //(A) Transactional Endpoint .transacted("required") //(B) TX Policy with PROPAGATION_REQUIRED and JPATxManager .bean("someBean", "readFromDB()") //(C) Read from DB .bean("someBean", "writeToDB()") //(D) Write to DB .to("file:/home/src?fileName=demo_${id}.txt")
我知道(A)的JMS使用者将在每次轮询中发送JMS事务,并附加到线程。此外,(B)中的事务节点将在交换到达JPA事务并连接到线程后发出JPA事务。
请找出我的问题如下:
注:我在第二版“骆驼”中没有找到任何明显的答案,所以请指导我
发布于 2020-03-10 20:21:16
下午好,
这是你另一个问题的一个变体。
以下方面:
from("jms:queue:IN_QUEUE) //(A) Transactional Endpoint端点被处理,这意味着您已经将JMS组件标记为事务,而JMS会话将由JmsTransactionManager管理。
.transacted("required") //(B) TX Policy with PROPAGATION_REQUIRED and
JPATxManager这不应该是JPA事务管理器,而应该是JTA事务管理器(比如Arjuna)。与您的另一个问题一样,您现在有一个用于读取消息的JMS本地事务,以及本地JPA为您的DB访问处理的会话。您希望PlatformTransactionManager (PlatformTransactionManager)为您同步本地事务。
至于你的问题:
两个不同的事务可以连接到一个线程上(如上面的一个)吗?
这真的没有任何意义。
如果是的话,哪一个应该停职?
什么都不会被暂停。
上述路由的提交和回滚顺序应该是什么?
DB读取不是事务性的,不需要提交。当JTA事务上下文关闭时,文件写入实际上就会发生。这就剩下DB写了。如果失败了,那么DB读取就无关紧要了,消息将被放回源目的地,而文件写也不会被调用。
为各种事务管理器启用调试日志记录非常有用。
我可以用痛苦的细节来继续这件事。这是给burki的更多。我想你会很感激的。非常微妙,而且经常发生。
from("jms:queue:SRC_QUEUE")
.transacted("required")
.to("jms1:queue:DEST_QUEUE") 如果这两个端点被标记为交易.但是..。你没有“交易”行吗?在消息侦听器上启动了JMS本地事务。这将在路线结束时提交。有两个独立的本地JMS事务。这些不是由JTA事务管理器同步的。
实际发生的情况是,消息'get‘的提交被调用。消息“put”没有实际提交。消息'put‘是在JMS会话关闭时提交的。这是在JMS规范中,关闭连接本质上提交了任何事务。因此,因为这两个组件之间没有联系,所以提交了'get‘,然后关闭了'put’会话。
这意味着,如果消息“get”的commit与消息“put”的会话关闭之间发生中断,则可能会丢失消息。
这有意义吗?本地事务之间没有联系,因此Camel按顺序关闭它们,首先提交“get”,然后调用“put”。
JTA事务同步是关键。您仍然拥有本地事务资源(不是XA),但是可以在相当轻量级的JTA事务上下文中很好地管理它们。
from("jms:queue:SRC_QUEUE")
.transacted("required")
.to("DB:transactedwrite")
.to("jms1:queue:DEST_QUEUE") 我不想为数据库插入查找正确的语法,但您知道了。在这种情况下,如果JMS 'put‘失败,您可以获得重复的DB插入。这不是“全部或无”XA事务。事务按顺序提交。如果中间的一个成功了,那么下一个事务就会失败,那么' get‘就会被回滚,并且您会得到重复到失败点。
发布于 2020-03-09 11:39:43
对不起,我不能回答你的具体问题,但是我可以提供一些关于你路线交易的具体信息。
您有三个不同的“系统”,具有不同的事务“范围”。
首先,--如果您希望跨JMS和数据库具有事务安全,则必须使用XA事务。
然后,还不清楚是否期望使用者进行事务处理(因为您的路由中有transacted() ),或者您的是否真正配置了与本地JMS的JMS连接。我猜你真的是在消费交易。
让我们来谈谈您的路线中没有B行的情况:
您所消费的来自代理的
。
由事务性使用者打开的事务一直由Camel打开,直到路由成功地处理为止。
因此,唯一明显的问题是在数据库写入后出现错误,这将触发重传,然后再次执行数据库写入。可能是,写不是幂等的,因此不能发生两次。
因此,要解决这些问题,要么必须使用XA事务,要么只需使用本地JMS事务,并为上面所述的“缺口”实现补偿逻辑。
另一方面,数据库事务没有好处,除非必须在事务中执行读和写操作(但我怀疑这是两个单独的bean调用和一个JMS使用者的情况)。
https://stackoverflow.com/questions/60557385
复制相似问题