1. 本地事务   

1.1. 在一个JMS客户端, 可以使用本地事务来组合消息的发送和接收。JMS Session接口提供了commit和rollback方法。事务提交意味着生产的所有消息被发送, 消费的所有消息被确认; 事务回滚意味着生产的所有消息被销毁, 消费的所有消息被恢复并重新提交, 除非它们已经过期。

1.2. 事务性的会话总是牵涉到事务处理中, commit或rollback方法一旦被调用, 一个事务就结束了, 而另一个事务被开始。关闭事务性会话将回滚其中的事务。

1.3. 需要注意的还有一个, 消息的生产和消费不能包含在同一个事务中。

2. 创建事务会话

2.1. 创建事务会话的时候transacted参数要设置为true, acknowledgeMode参数要设置为Session.SESSION_TRANSACTED。

// 1. 创建一个连接工厂
ConnectionFactory cf = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, ActiveMQConnection.DEFAULT_BROKER_URL);
// 2. 创建连接
Connection conn = cf.createConnection();
// 4. 创建会话
Session session = conn.createSession(true, Session.SESSION_TRANSACTED);

2.2. Session.SESSION_TRANSACTED值是专门为事务会话使用的。

3. 例子

3.1. 创建一个名为JMSTransacted的Java项目, 同时拷入相关jar包

3.2. 编辑MyProducer.java

package com.jmsapp.tra;import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;public class MyProducer {// 默认连接用户名private static final String dftUsr = ActiveMQConnection.DEFAULT_USER;// 默认用户密码private static final String dftPwd = ActiveMQConnection.DEFAULT_PASSWORD;// 默认连接地址private static final String dftUrl = ActiveMQConnection.DEFAULT_BROKER_URL;// 队列名称private static final String queueName = "queueMapMsgTransacted";public static void main(String[] args) {// 1. 创建一个连接工厂QueueConnectionFactory cf = new ActiveMQConnectionFactory(dftUsr, dftPwd, dftUrl);// 连接对象QueueConnection conn = null;// 会话对象QueueSession session = null;try {// 2. 创建连接conn = cf.createQueueConnection();// 3. 启动连接conn.start();// 4. 创建会话session = conn.createQueueSession(true, Session.SESSION_TRANSACTED);// 5. 创建消息目的地。如果是点对点, 那么它的实现是Queue; 如果是订阅模式, 那它的实现是Topic。这里我们创建一个名为queueMapMsgTransacted的消息队列。Queue queue = session.createQueue(queueName);// 6. 消息生产者QueueSender sender = session.createSender(null);// 7. 创建文本消息和发送消息MapMessage user = session.createMapMessage();user.setLong("id", 100000000000L);user.setString("name", "lisi");sender.send(queue, user, DeliveryMode.PERSISTENT, 9, 1000 * 60 * 60);MapMessage userExtend = session.createMapMessage();userExtend.setChar("sex", '男');userExtend.setBoolean("married", false);sender.send(queue, userExtend, DeliveryMode.PERSISTENT, 5, 1000 * 60 * 60);// 8. 提交事务session.commit();} catch (JMSException e) {if(null != session) {try {session.rollback();} catch (JMSException e1) {e1.printStackTrace();}}e.printStackTrace();} finally {try {if (session != null) {session.close();}} catch (JMSException e1) {e1.printStackTrace();} finally {if (conn != null) {try {conn.close();} catch (JMSException e) {e.printStackTrace();}}}}}
}

3.3. 点对点消息过期, 会把它存放到一个ActiveMQ.DLQ的队列中

3.4. 编辑MyConsumer.java

package com.jmsapp.tra;import java.util.Enumeration;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueReceiver;
import javax.jms.QueueSession;
import javax.jms.Session;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;public class MyConsumer {// 默认连接用户名private static final String dftUsr = ActiveMQConnection.DEFAULT_USER;// 默认用户密码private static final String dftPwd = ActiveMQConnection.DEFAULT_PASSWORD;// 默认连接地址private static final String dftUrl = ActiveMQConnection.DEFAULT_BROKER_URL;// 队列名称private static final String queueName = "queueMapMsgTransacted";public static void main(String[] args) {// 1. 创建一个连接工厂QueueConnectionFactory cf = new ActiveMQConnectionFactory(dftUsr, dftPwd, dftUrl);// 连接对象QueueConnection conn = null;// 会话对象QueueSession session = null;try {// 2. 创建连接conn = cf.createQueueConnection();// 3. 启动连接conn.start();// 4. 创建会话session = conn.createQueueSession(true, Session.SESSION_TRANSACTED);// 5. 创建消息目的地。如果是点对点, 那么它的实现是Queue; 如果是订阅模式, 那它的实现是Topic。这里我们创建一个名为queueMapMsgTransacted的消息队列。Queue queue = session.createQueue(queueName);// 6. 消息接收者QueueReceiver receiver = session.createReceiver(queue);// 7. 创建文本消息和发送消息while(true) {MapMessage msg = (MapMessage) receiver.receive(3000);if(msg == null) {break;}@SuppressWarnings("unchecked")Enumeration<String> e = msg.getMapNames();while(e.hasMoreElements()) {String name =  e.nextElement();System.out.println(name + " = " + msg.getObject(name));}}// 8. 提交事务session.commit();} catch (JMSException e) {if(null != session) {try {session.rollback();} catch (JMSException e1) {e1.printStackTrace();}}e.printStackTrace();} finally {try {if (session != null) {session.close();}} catch (JMSException e1) {e1.printStackTrace();} finally {if (conn != null) {try {conn.close();} catch (JMSException e) {e.printStackTrace();}}}}}
}

3.5. 再次运行MyProducer.java, 然后运行MyConsumer.java

009_JMS中的事务相关推荐

  1. Redis初学:14(Redis中的事务)

    Redis中的事务 Redis的事务定义 Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的命令请求所打断. Redis事务的主 ...

  2. SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因...

    原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...

  3. mysql sql 事务写作_mysql中的事务

    MySQL事务相关 一. 什么是事务 事务(Transaction)是一个逻辑序列,该序列要么执行,要么不执行. 例如:转换业务 A 给 B 转账 1000 元,设计两个操作: A减少1000元 B增 ...

  4. MySQL数据库中默认事务隔离级别是?

    MySQL数据库中默认事务隔离级别是? 事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到 ...

  5. springboot事务回滚源码_Spring Boot中的事务是如何实现的

    1. 概述 一直在用SpringBoot中的@Transactional来做事务管理,但是很少想过SpringBoot是如何实现事务管理的,今天从源码入手,看看@Transactional是如何实现事 ...

  6. Spring中的事务管理详解

    在这里主要介绍Spring对事务管理的一些理论知识,实战方面参考上一篇博文: http://www.cnblogs.com/longshiyVip/p/5061547.html 1. 事务简介: 事务 ...

  7. 具体解释Hibernate中的事务

    1.前言 上一篇博客解说了Hibernate中的一级缓存,属于Session级别的.这篇博客解说一下Hibernate中的事务机制. 有关事务的概念.请參照通俗易懂数据库中的事务.  2.怎样处理Hi ...

  8. mysql中不同事务隔离级别下数据的显示效果--转载

    事务是一组原子性的SQL查询语句,也可以被看做一个工作单元.如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一条查询语句因为崩溃或其他原因而无法执行,那么所有的语句就都 ...

  9. spring中的事务配置

    为什么80%的码农都做不了架构师?>>>    一 简介 spring中提供了三种事务管理的方法. 编程式事务管理 :亦即自己编写事务管理的代码,通过注入获取到spring中的事务管 ...

最新文章

  1. WSAGetLastError:10004 一个封锁操作被对 WSACancelBlockingCall的调用中断 的解决
  2. 地图漫游功能的具体体现_骏谷科技|数据中心三维可视化管理系统功能亮点
  3. boost::core模块实现分配器分配提示
  4. redis设置开机自启动
  5. 音视频技术开发周刊 60期
  6. python断言assertequal_python-尝试断言AlmostEqual / assertEqual时,不受支持的操作数类型...
  7. 云计算:企业商业模式创新的新战线
  8. 39策略模式(Strategy Pattern)
  9. mongodb学习笔记之增删改查作指令
  10. Qt容器类(总结)(新发现的QQueue和QStack,注意全都是泛型)
  11. mysql利用tgz恢复_Mysql备份与恢复方法_MySQL
  12. 面试回忆之四:所投职位和背景极端不匹配的简历
  13. 牛客网——程序员代码面试指南(更新ing)
  14. 前端实现数据base64解码
  15. JAVA练习10-累加数
  16. 以太坊链上的二层(layer2)扩容方案Matic(Polygon)
  17. 渗透测试-安全岗位面试题总结(含答案)
  18. 笔记本计算机在桌面显示器,解决笔记本电脑屏幕出现条纹的五大方法
  19. 连接远程计算机提示:“这可能是由于CredSSP加密数据库修正” 问题
  20. 我的世界java版如何看坐标_坐标 - Minecraft Wiki,最详细的官方我的世界百科

热门文章

  1. eclipse中使用svn提交,更新代码。
  2. [原创] 浅谈ETL系统架构如何测试?
  3. 【转载】如何使用STM32的窗口看门狗
  4. Argus(ZOJ Problem Set - 2212)(优先队列)
  5. vsftpd 默认配置文件
  6. IDEA 引入传统 j2ee spring mvc
  7. apache http server指的是什么
  8. 企业网络带宽需求和跨地域网络连接的优化
  9. 论坛服务软件Discux_X3.4的部署
  10. 已被管理员、加密政策或凭据存储停用