JMS与数据库事务

简介:

发送消息时的事务

THREAD系统中使用spring的JmsTemplate组件来发送消息。这是我们THREAD系统中的配置:

<beanid="newJmsTemplate"class="org.springframework.jms.core.JmsTemplate">

<propertyname="connectionFactory"ref="jmsConnectionFactory"/>

<propertyname="sessionTransacted"value="true"/>

<propertyname="explicitQosEnabled"value="${activemq.explicitQosEnabled}"/>

<propertyname="timeToLive"value="86400000"/>

bean>

其中“”这一行就是发送消息时的事务配置。有了这个配置之后,Jms消息发送就与事务绑定上了。


而它在事务中的行为还与transactionManager有关。这是我们THREAD系统中的transactionManager配置:

<beanid="transactionManager"

class="org.springframework.orm.hibernate4.HibernateTransactionManager">

<propertyname="sessionFactory"ref="sessionFactory"/>

<propertyname="nestedTransactionAllowed"value="true"/>

<propertyname="globalRollbackOnParticipationFailure"value="false"/>

bean>

在这个transactionManager配置下,Jms消息会在afterCommit()操作中提交。如下图所示。

image2016-9-8%2018%3A18%3A3.png?version=


根据网上的文章,如果要保证jms操作和数据库操作真正做到“同生共死”,必须使用JTATransactionManager。但是这个东东的性能一直是个问题。

<tx:jta-transaction-manager/>



接收消息时的重发机制

接收消息后的重发机制与数据库事务之间的关系,并没有像发送消息时那样严格的绑定在一起。也就是说,接收消息后是否重试与数据库事务没有必然的关系。

一般来说,做到以下两点,就可以实现重试。

首先,在listener的配置中增加“acknowledge="transacted"”,如下所示。

<jms:listener-containerdestination-type="queue"

concurrency="4"acknowledge="transacted"connection-factory="connectionFactory">

<jms:listenerdestination="queue.thread.autopay"ref="autoPayListener"/>

jms:listener-container>

第二,当消息处理失败后,抛出异常。

@Override

publicvoidonMessage(Message message) {

try{

// 省略业务处理代码

catch(Exception e) {

// 省略日志、监控邮件等代码

// 抛出异常,让MQ重发一次消息。

throwinstanceofRuntimeException ? (RuntimeException) e

newRuntimeException(e);

}

}


默认的消息重发规则配置在org.apache.activemq.RedeliveryPolicy类中。从代码上看,默认会重发6次。如果需要修改默认配置,可以参考THREAD中spring-modules.xml文件中的配置:

<amq:connectionFactoryid="connectionFactory"brokerURL="tcp://${jms.url}:61616">

<amq:redeliveryPolicyMap>

<amq:redeliveryPolicyMap>

<amq:defaultEntry>

<amq:redeliveryPolicymaximumRedeliveries="5"initialRedeliveryDelay="30000"/>

amq:defaultEntry>

<amq:redeliveryPolicyEntries>

<amq:redeliveryPolicyqueue="queue.thread.autopay"maximumRedeliveries="5"

initialRedeliveryDelay="10000"/>

<amq:redeliveryPolicyqueue="queue.thread.instantUnionpay"maximumRedeliveries="5"

initialRedeliveryDelay="90000"/>

amq:redeliveryPolicyEntries>

amq:redeliveryPolicyMap>

amq:redeliveryPolicyMap>

amq:connectionFactory>


如果重试次数超过上限,MQ会将消息转到另一个“投递失败队列”(Dead Letter Queue)中。“投递失败队列”的名称一般就是“DLQ.原队列名”。




本文转自 斯然在天边 51CTO博客,原文链接:http://blog.51cto.com/winters1224/1879786,如需转载请自行联系原作者

相关文章
|
4月前
|
SQL 关系型数据库 MySQL
乐观锁在分布式数据库中如何与事务隔离级别结合使用
乐观锁在分布式数据库中如何与事务隔离级别结合使用
|
2月前
|
SQL 关系型数据库 MySQL
乐观锁在分布式数据库中如何与事务隔离级别结合使用
乐观锁在分布式数据库中如何与事务隔离级别结合使用
|
5天前
|
SQL 存储 Java
数据库———事务及bug的解决
事务的一些概念,并发事务以及并发事务引起的bug,脏读,不可重复读,幻读,数据库中的隔离级别,事务的简单应用
|
4月前
|
SQL 数据库 数据安全/隐私保护
SQL Server数据库Owner导致事务复制log reader job无法启动的解决办法
【8月更文挑战第14天】解决SQL Server事务复制Log Reader作业因数据库所有者问题无法启动的方法:首先验证数据库所有者是否有效并具足够权限;若非,使用`ALTER AUTHORIZATION`更改为有效登录名。其次,确认Log Reader使用的登录名拥有读取事务日志所需的角色权限。还需检查复制配置是否准确无误,并验证Log Reader代理的连接信息及参数。重启SQL Server Agent服务或手动启动Log Reader作业亦可能解决问题。最后,审查SQL Server错误日志及Windows事件查看器以获取更多线索。
|
6月前
|
存储 关系型数据库 MySQL
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
|
2月前
|
数据库
什么是数据库的事务隔离级别,有什么作用
【10月更文挑战第21】什么是数据库的事务隔离级别,有什么作用
26 3
|
2月前
|
存储 关系型数据库 数据挖掘
什么是数据库的事务隔离级别
【10月更文挑战第21】什么是数据库的事务隔离级别
39 1
|
2月前
|
存储 数据库 数据库管理
数据库事务安全性控制如何实现呢
【10月更文挑战第15天】数据库事务安全性控制如何实现呢
|
2月前
|
存储 数据库 数据库管理
什么是数据库事务安全性控制
【10月更文挑战第15天】什么是数据库事务安全性控制
|
2月前
|
供应链 数据库
数据库事务安全性控制有什么应用场景吗
【10月更文挑战第15天】数据库事务安全性控制有什么应用场景吗