009_JMS中的事务
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中的事务相关推荐
- Redis初学:14(Redis中的事务)
Redis中的事务 Redis的事务定义 Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的命令请求所打断. Redis事务的主 ...
- SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因...
原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...
- mysql sql 事务写作_mysql中的事务
MySQL事务相关 一. 什么是事务 事务(Transaction)是一个逻辑序列,该序列要么执行,要么不执行. 例如:转换业务 A 给 B 转账 1000 元,设计两个操作: A减少1000元 B增 ...
- MySQL数据库中默认事务隔离级别是?
MySQL数据库中默认事务隔离级别是? 事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到 ...
- springboot事务回滚源码_Spring Boot中的事务是如何实现的
1. 概述 一直在用SpringBoot中的@Transactional来做事务管理,但是很少想过SpringBoot是如何实现事务管理的,今天从源码入手,看看@Transactional是如何实现事 ...
- Spring中的事务管理详解
在这里主要介绍Spring对事务管理的一些理论知识,实战方面参考上一篇博文: http://www.cnblogs.com/longshiyVip/p/5061547.html 1. 事务简介: 事务 ...
- 具体解释Hibernate中的事务
1.前言 上一篇博客解说了Hibernate中的一级缓存,属于Session级别的.这篇博客解说一下Hibernate中的事务机制. 有关事务的概念.请參照通俗易懂数据库中的事务. 2.怎样处理Hi ...
- mysql中不同事务隔离级别下数据的显示效果--转载
事务是一组原子性的SQL查询语句,也可以被看做一个工作单元.如果数据库引擎能够成功地对数据库应用所有的查询语句,它就会执行所有查询,如果任何一条查询语句因为崩溃或其他原因而无法执行,那么所有的语句就都 ...
- spring中的事务配置
为什么80%的码农都做不了架构师?>>> 一 简介 spring中提供了三种事务管理的方法. 编程式事务管理 :亦即自己编写事务管理的代码,通过注入获取到spring中的事务管 ...
最新文章
- WSAGetLastError:10004 一个封锁操作被对 WSACancelBlockingCall的调用中断 的解决
- 地图漫游功能的具体体现_骏谷科技|数据中心三维可视化管理系统功能亮点
- boost::core模块实现分配器分配提示
- redis设置开机自启动
- 音视频技术开发周刊 60期
- python断言assertequal_python-尝试断言AlmostEqual / assertEqual时,不受支持的操作数类型...
- 云计算:企业商业模式创新的新战线
- 39策略模式(Strategy Pattern)
- mongodb学习笔记之增删改查作指令
- Qt容器类(总结)(新发现的QQueue和QStack,注意全都是泛型)
- mysql利用tgz恢复_Mysql备份与恢复方法_MySQL
- 面试回忆之四:所投职位和背景极端不匹配的简历
- 牛客网——程序员代码面试指南(更新ing)
- 前端实现数据base64解码
- JAVA练习10-累加数
- 以太坊链上的二层(layer2)扩容方案Matic(Polygon)
- 渗透测试-安全岗位面试题总结(含答案)
- 笔记本计算机在桌面显示器,解决笔记本电脑屏幕出现条纹的五大方法
- 连接远程计算机提示:“这可能是由于CredSSP加密数据库修正” 问题
- 我的世界java版如何看坐标_坐标 - Minecraft Wiki,最详细的官方我的世界百科