Spring提供了一个JmsTransactionManager用于对JMS ConnectionFactory做事务管理。这将允许JMS应用利用Spring的事务管理特性。JmsTransactionManager在执行本地资源事务管理时将从指定的ConnectionFactory绑定一个ConnectionFactory/Session这样的配对到线程中。JmsTemplate会自动检测这样的事务资源,并对它们进行相应操作。

在Spring整合JMS的应用中,如果我们要进行本地的事务管理的话非常简单,只需要在定义对应的消息监听容器时指定其sessionTransacted属性为true。

xml: 增加<property name="sessionTransacted" value="true"/>

<!--配置 消息监听容器-->
<bean id="jmsContainer" class=" org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destination" ref="queueDestination"/>
<property name="messageListener" ref="consumerMessageListener"/>
<!--应答模式是 INDIVIDUAL_ACKNOWLEDGE-->
<!--AUTO_ACKNOWLEDGE = 1 自动确认
CLIENT_ACKNOWLEDGE = 2 客户端手动确认
DUPS_OK_ACKNOWLEDGE = 3 自动批量确认
SESSION_TRANSACTED = 0 事务提交并确认
INDIVIDUAL_ACKNOWLEDGE = 4 单条消息确认-->
<property name="sessionAcknowledgeMode" value="4"/>
<!--对消息开启事务模式-->
<property name="sessionTransacted" value="true"/>
</bean>

监听器加入session.rollback();消息进行回滚重传(上一篇中因为还没有学习回滚,所以用的session.recover()实现的重发,现在就可以使用事务rollback()方法实现了)

回滚的过程是消息先出列,然后重发,默认6次,超过次数后进入到死亡队列,(配置持久化数据库的时候,并持久化到数据库一条数据);

回滚肯定是开启了事务的情况下,那么没有开启事务的情况呢?消息没有确认的情况,消息会停在消息队列中,等待着再次被监听,除非调用session.recover()方法,效果和开启事务并回滚一样会进入死亡队列。

   session.rollback();//手动的调用此方法进行回滚,抛出异常时实际上事务开启后会自动进行回滚的。

调用commit()方法进行提交:值得说的是,在事务模式下,在接收消息没有确认的情况也会出列。完成消息。

 session.commit();

也就是说,开启事务后消息永远不会出现停留在队列的情况,消息会回滚重发,最后到死亡队列中,而不开启事务的情况,只要不使用session.recover();消息会停留在队列中,不会重发,直至被确认出列。如果调用了recover就和回滚重发一样了。

我们在实际业务中,接收消息操作和数据库操作要在一起进行那么该怎么控制事务呢?

Spring里,如果同时存在JMS操作和DB操作,大概也就三种方式:

1.没有使用JTA。JMS不在事务中,DB操作在事务中

a,消息处理

b,开始数据库事务

c,数据库操作

d,数据库提交

成功:结束

失败:回到b重试

这种方式事务没有集成,靠的纯粹是我们程序的控制,如果最终数据库提交都没成功的话,可以记下log,再人工去纠正数据。例子里把数据库操作放在了更重要的位置,其实也可以倒过来,让数据库操作先完成,只好在做jms操作,看业务需求了:

a,开始数据库事务

b,数据库操作

c,数据库提交

d,消息处理

成功:结束

失败:回到d重试

我们只要把spring配置改成

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
...
<!-- This is important... -->
<property name="sessionTransacted" value="false" />
</bean>
 
再加上自己程序控制就好了。

2.如果没有使用JTA,对于上面的配置如果把属性 sessionTransacted 设成true的话,就产生了第二种方式,过程:

a,开始jms事务

b,开始数据库事务

c,数据库和jms操作

d,提交数据库操作

e,提交jms操作

a,b的顺序不肯定,不过对程序没影响,但是d,e的顺序是确定的。在Spring里,数据库会在spring的commit方法里提交,而JMS会在afterCommit方法里提交。如果数据库失败,JMS当然也就回滚了,但是如果数据库成功而JMS失败,就产生了数据不一致,就要加上其它措施。而且这里还有一个致命缺点,就是某些情况下即使JMS失败(比如JMS服务器down了),Spring也不会抛出异常,程序外部以为一切正常,而事实上以产生了不一致问题,而且很难发现。

3.如果使用了JTA那么把属性 sessionTransacted 设成true的话,

JMS和数据库操作就在同一个事务里了,没什么好说,最安全的方式,但是效率很低。

  

学习ActiveMQ(七):JMS消息的事务管理的更多相关文章

  1. ActiveMQ基本详解与总结& 消息队列-推/拉模式学习 & ActiveMQ及JMS学习

    转自:https://www.cnblogs.com/Survivalist/p/8094069.html ActiveMQ基本详解与总结 基本使用可以参考https://www.cnblogs.co ...

  2. SpringBoot+Shiro学习(七):Filter过滤器管理

    SpringBoot+Shiro学习(七):Filter过滤器管理 Hiwayz 关注  0.5 2018.09.06 19:09* 字数 1070 阅读 5922评论 1喜欢 20 先从我们写的一个 ...

  3. 消息队列-推/拉模式学习 & ActiveMQ及JMS学习

    一种分类是推和拉 . 还有一种分类是 Queue 和 Pub/Sub . 先看的这一篇:http://blog.csdn.net/heyutao007/article/details/50131089 ...

  4. ActiveMQ的JMS消息可靠机制

    JMS消息可靠机制 ActiveMQ消息签收机制: 客戶端成功接收一条消息的标志是一条消息被签收,成功应答. 消息的签收情形分两种: 1.带事务的session 如果session带有事务,并且事务成 ...

  5. 深入学习Spring框架(四)- 事务管理

    1.什么是事务? 事务(Transaction)是一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位,是数据库环境中的逻辑工作单位.事务是为了保证数据库的完整性.例如:A给B转账,需 ...

  6. 使用ActiveMQ实现JMS消息通信服务

    PTP(点对点的消息模型) 在点对点模型中,相当于两个人打电话,两个人独享一条通信线路.一方发送消息,一方接收消息. 在p2p的模型中,双方通过队列交流,一个队列只有一个生产者和一个消费者. 1.建立 ...

  7. 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring声明式事务管理(基于Annotation注解方式实现)

    在 Spring 中,除了使用基于 XML 的方式可以实现声明式事务管理以外,还可以通过 Annotation 注解的方式实现声明式事务管理. 使用 Annotation 的方式非常简单,只需要在项目 ...

  8. Spring学习笔记五:Spring进行事务管理

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6776256.html  事务管理主要负责对持久化方法进行统一的提交或回滚,Spring进行事务管理即我们无需在 ...

  9. 使用Tomcat、JNDI与ActiveMQ实现JMS消息通信服务

    前言 之所以使用JNDI 是出于通用性考虑,该例子使用JMS规范提供的通用接口,没有使用具体JMS提供者的接口,这样可以保证我们编写的程序适用于任何一种JMS实现(ActiveMQ.HornetQ等) ...

随机推荐

  1. css布局中的百分比布局

    1.在说到百分比是前,先简单了解下基本的单位 英寸(inch) :in 1 in=2.54cm厘米(centimeter):cm毫米(millimeter):mm磅(point):pt 1pt=1/7 ...

  2. I2C与EEPROM

    一.基本概念 RAM(Random Access Memory)的全名为随机存取记忆体,它相当于PC机上的移动存储,用来存储和保存数据的.它在任何时候都可以读写,RAM 通常是作为操作系统或其他正在运 ...

  3. .Net IOC框架入门之三 Autofac

    一.简介   Autofac是.NET领域最为流行的IOC框架之一,传说是速度最快的一个 目的 1.依赖注入的目的是为了解耦. 2.不依赖于具体类,而依赖抽象类或者接口,这叫依赖倒置. 3.控制反转即 ...

  4. C++设计模式——桥接模式

    问题描述 现在要去画一个图形,图形有长方形.圆形和扇形等等:而图形又可以加上不同的颜色,然后,我们就可以画出红色的长方形,绿色的长方形:红色的圆形,绿色的圆形等等.而这种图形的形状在变化,图形的颜色也 ...

  5. 【原创】大数据基础之Spark(3)Spark Thrift实现原理及代码实现

    spark 2.1.1 一 启动命令 启动spark thrift命令 $SPARK_HOME/sbin/start-thriftserver.sh 然后会执行 org.apache.spark.de ...

  6. 【原创】Linux基础之用户和组

    1 添加.删除用户 # useradd $user# userdel $user 2 设置用户密码 # passwd $user /etc/passwd 3 查看$user的用户和组信息 # id $ ...

  7. linux 解决Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

    第一种: sudo vim /etc/resolv.conf 添加nameserver 8.8.8.8 第二种: /etc/apt/sources.list 的内容换成 deb http://old- ...

  8. TF-tf.arg_max 介绍

    定义为 def arg_max(input, dimension, name=None) 作用是取行或者列的最大值的位置. input:类型为 float32, float64, int64, int ...

  9. Expression Trees 参数简化查询

    ASP.NET MVC 引入了 ModelBinder 技术,让我们可以在 Action 中以强类型参数的形式接收 Request 中的数据,极大的方便了我们的编程,提高了生产力.在查询 Action ...

  10. 编译linux内核前用make menuconfig设置时 Unable to find the ncurses ibraries的解决办法

    今天在更新CentOS或者Ubuntu的内核时,执行make menuconfig可能看如这样的错误: *** Unable to find the ncurses libraries or the ...