首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JDBC和JMS的Spring事务同步

JDBC和JMS的Spring事务同步
EN

Stack Overflow用户
提问于 2012-02-10 22:47:46
回答 3查看 14.2K关注 0票数 21

我有一个运行在jboss上的spring web应用程序,它当前被配置为使用用于数据库事务的HibernateTransactionManager和用于jms的JmsTransactionManager。对于jms,我们使用Camel和ActiveMQ,我们的数据库是DB2。在一个事务中,我需要向数据库写入许多记录,并发送两个异步jms消息。jms消息是事件通知,我只希望在数据库事务提交时发送它们。

我愿意承担在jdbc事务已经提交之后与代理的通信失败的风险(因此没有发送消息,但是提交了数据库),所以我认为我不需要适当的XA。

我认为我需要的是使用spring事务同步的“尽力而为”的事务管理。

spring文档在某种程度上暗示了一个事实,即spring将同步这两个事务,并仅在jdbc事务提交之后才提交jms事务-但我认为这并不是很清楚。这里的spring文档http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#tx-resource-synchronization没有详细介绍它是如何工作的。

我找到了一些其他来源,包括下面的一些javadoc,它们说spring会做我想做的事情,我也写了一些集成测试来证明这一点。

setSessionTransacted上的http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/jms/support/JmsAccessor.html#setSessionTransacted%28boolean%29听起来就是我想要的。

根据我所看到的,我认为像这样创建事务处理设置为true的驼峰JmsConfiguration就足够了:

代码语言:javascript
复制
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
    <property name="connectionFactory" ref="pooledConnectionFactory"/>
    <property name="transacted" value="true"/>
    <property name="concurrentConsumers" value="10"/>
</bean>

然而,我需要说服与我一起工作的人,他有点怀疑,认为我的集成测试之所以有效,是因为有很少的记录的副作用,而不是有意的spring特性。

所以我的问题是- spring可以被用来同步事务并总是在jdbc事务之后提交jms事务,这是正确的吗?或者这不是我应该依赖的东西,您能在任何明确说明这一点的官方文档中告诉我吗?我猜,总的来说,这是一种好的方法,还是我们应该以不同的方式管理这些事务?

EN

回答 3

Stack Overflow用户

发布于 2012-02-10 23:25:57

这篇文章可能会对Distributed transactions in Spring, with and without XA有所帮助。我不认为它特别涵盖了你的情况--发送消息+更新数据库。

票数 3
EN

Stack Overflow用户

发布于 2015-07-13 03:59:02

官方的Spring Boot存储库包含基于AtomikosBitronixJava EE server JBoss WildFly将JMS与JDBC相结合的JTA示例。

此外,我还创建了一些located in my Github repository示例。这也包含非Spring Boot (纯Spring)示例。

票数 1
EN

Stack Overflow用户

发布于 2016-12-24 16:45:07

如果您使用的是本地事务,并且用例是保存到数据库,然后发送到jms

那么可能有三种情况:

收到(数据库和JMS之前)

  1. 后发生

异常

没有问题,所有内容都将回滚

  1. 在保存到数据库后,出现exception

如果有insert操作,由于每次重试,数据库中将有多个行,insert将为done.And

JMS,消息将发送到DeadLetterQueue

  1. 保存到数据库并发送到JMS后,如果有insert操作,我们会有一个异常,每次重试时,由于retries.With会在数据库中有多个行,insert将为done.And for JMS,消息将转到DeadLetterQueue

现在您不想使用XA,因此解决方案可能是

1)检查(message.getJmsRedelivered() {…}

如果不是,则处理它

如果重新发送,请检查您是否已经处理过

根据消息中的详细信息检查数据是否在数据库中

请注意,重新发送的情况很少,因此,这种检查也很少见,并且没有开销

2)如果你的方法是幂等的,那么你不需要这个检查

关于XA,XA保证消息只传递一次,并且跨多个资源同步事务

但是使用XA,您需要额外的开销

因此,如果您可以在没有XA的情况下管理,则更可取

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

https://stackoverflow.com/questions/9229573

复制
相关文章

相似问题

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