首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >事务路由和事务端点,事务提交顺序

事务路由和事务端点,事务提交顺序
EN

Stack Overflow用户
提问于 2020-03-06 04:01:25
回答 2查看 351关注 0票数 0

我的路线如下所示

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事务。

请找出我的问题如下:

  1. 可以将两个不同的事务附加到单个线程(如上面的线程)?
  2. ,如果是,哪个事务应该被挂起?
  3. ,上面提到的路由的提交和回滚顺序应该是什么?

注:我在第二版“骆驼”中没有找到任何明显的答案,所以请指导我

EN

回答 2

Stack Overflow用户

发布于 2020-03-10 20:21:16

下午好,

这是你另一个问题的一个变体。

以下方面:

代码语言:javascript
复制
from("jms:queue:IN_QUEUE)      //(A) Transactional Endpoint

端点被处理,这意味着您已经将JMS组件标记为事务,而JMS会话将由JmsTransactionManager管理。

代码语言:javascript
复制
.transacted("required")   //(B) TX Policy with PROPAGATION_REQUIRED and 
JPATxManager

这不应该是JPA事务管理器,而应该是JTA事务管理器(比如Arjuna)。与您的另一个问题一样,您现在有一个用于读取消息的JMS本地事务,以及本地JPA为您的DB访问处理的会话。您希望PlatformTransactionManager (PlatformTransactionManager)为您同步本地事务。

至于你的问题:

两个不同的事务可以连接到一个线程上(如上面的一个)吗?

这真的没有任何意义。

如果是的话,哪一个应该停职?

什么都不会被暂停。

上述路由的提交和回滚顺序应该是什么?

DB读取不是事务性的,不需要提交。当JTA事务上下文关闭时,文件写入实际上就会发生。这就剩下DB写了。如果失败了,那么DB读取就无关紧要了,消息将被放回源目的地,而文件写也不会被调用。

为各种事务管理器启用调试日志记录非常有用。

我可以用痛苦的细节来继续这件事。这是给burki的更多。我想你会很感激的。非常微妙,而且经常发生。

代码语言:javascript
复制
   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事务上下文中很好地管理它们。

代码语言:javascript
复制
   from("jms:queue:SRC_QUEUE")
     .transacted("required")
     .to("DB:transactedwrite")
     .to("jms1:queue:DEST_QUEUE") 

我不想为数据库插入查找正确的语法,但您知道了。在这种情况下,如果JMS 'put‘失败,您可以获得重复的DB插入。这不是“全部或无”XA事务。事务按顺序提交。如果中间的一个成功了,那么下一个事务就会失败,那么' get‘就会被回滚,并且您会得到重复到失败点。

票数 1
EN

Stack Overflow用户

发布于 2020-03-09 11:39:43

对不起,我不能回答你的具体问题,但是我可以提供一些关于你路线交易的具体信息。

您有三个不同的“系统”,具有不同的事务“范围”。

  • 是JMS,您从其中使用
  • 数据库,并将JPA TxManager用于
  • A文件系统(完全没有事务)配置为目标

首先,--如果您希望跨JMS和数据库具有事务安全,则必须使用XA事务

然后,还不清楚是否期望使用者进行事务处理(因为您的路由中有transacted() ),或者您的是否真正配置了与本地JMS的JMS连接。我猜你真的是在消费交易。

让我们来谈谈您的路线中没有B行的情况:

您所消费的来自代理的

  • Camel通过路由
  • 处理消息,当在路由处理过程中发生任何错误时,该消息不会提交到代理上,因此将重新传递给路由

由事务性使用者打开的事务一直由Camel打开,直到路由成功地处理为止。

因此,唯一明显的问题是在数据库写入后出现错误,这将触发重传,然后再次执行数据库写入。可能是,写不是幂等的,因此不能发生两次。

因此,要解决这些问题,要么必须使用XA事务,要么只需使用本地JMS事务,并为上面所述的“缺口”实现补偿逻辑。

另一方面,数据库事务没有好处,除非必须在事务中执行读和写操作(但我怀疑这是两个单独的bean调用和一个JMS使用者的情况)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60557385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档