AMQ学习笔记 - 17. 事务的测试
概述
测试实例
测试实例 | 结果预测 |
发送正常 | 3条消息入队 |
发送异常 | 0条消息入队 |
接收正常 | 3条消息出队 |
接收异常 | 0条消息出队 |
demo设计
设计图

测试分工
测试类 | 测试方法 |
TransactedProducer.java - 测试发送 |
sendNormal():void - 测试“发送正常” |
sendIntentional():void - 测试“发送异常” |
|
TransactedConsumer.java - 测试接收 |
receiveNormal():void - 测试“接收正常” |
receiveIntentional():void - 测试“接收异常” |
测试步骤和结果
1.测试发送
1.1.测试发送正常
测试步骤 |
|
测试结果 |
符合预期。 |
1.2.测试发送异常
测试步骤 |
|
测试结果 |
符合预期。 |
2.测试接收
2.1.测试接收正常
测试步骤 |
|
测试结果 |
符合预期。 |
2.2.测试接收异常
测试步骤 |
|
测试结果 |
符合预期。 |
代码
文件目录结构
jms-producer
|---- src/main/resources/
|---- jndi.properties
|---- src/main/java/
|---- cn.sinobest.asj.producer.jms.transaction
|---- TransactedProducer.java # 测试发送
jms-consumer
|---- src/main/resources/
|---- jndi.properties # 和jms-producer中的jndi.properties一致
|---- src/main/java/
|---- cn.sinobest.asj.consumer.jms.transaction
|---- TransactedConsumer.java # 测试接收
文件内容
1.jndi.propertie
java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory # use the following property to configure the default connector
java.naming.provider.url=tcp://localhost:61616 # register some queues in JNDI using the form
# queue.[jndiName] = [physicalName]
queue.exampleQueue=example.queue # register some topics in JNDI using the form
# topic.[jndiName] = [physicalName]
topic.exampleTopic=example.topic
2.TransactedProducer.java
package cn.sinobest.asj.producer.jms.transaction;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.junit.Test;
/**
* 事务的生产者.<br>
* 测试发送正常和发送异常.
* @author lijinlong
*
*/
public class TransactedProducer {
/** JNDI name for ConnectionFactory */
static final String CONNECTION_FACTORY_JNDI_NAME = "ConnectionFactory";
/** JNDI name for Queue Destination (use for PTP Mode) */
static final String QUEUE_JNDI_NAME = "exampleQueue"; /** 是否故意异常 */
boolean intentional = false; /**
* 测试发送正常.
*/
@Test
public void sendNormal() {
this.intentional = false;
send(QUEUE_JNDI_NAME);
} /**
* 测试发送异常.
*/
@Test
public void sendIntentional() {
this.intentional = true;
send(QUEUE_JNDI_NAME);
} /**
* 是否故意抛出异常.<br>
* 如果不抛出异常,会有3条消息入队;否则没有消息入队.
* @return
*/
private boolean isIntentional() {
return intentional;
} /**
* 发送到指定的目的地.
*
* @param destJndiName
* 目的地的JNDI name.
*/
private void send(String destJndiName) {
Context jndiContext = null;
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Destination destination = null;
MessageProducer producer = null;
// create a JNDI API IntialContext object
try {
jndiContext = new InitialContext();
} catch (NamingException e) {
System.out.println("Could not create JNDI Context:"
+ e.getMessage());
System.exit(1);
}
// look up ConnectionFactory and Destination
try {
connectionFactory = (ConnectionFactory) jndiContext
.lookup(CONNECTION_FACTORY_JNDI_NAME);
destination = (Destination) jndiContext.lookup(destJndiName);
} catch (NamingException e) {
System.out.println("JNDI look up failed:" + e.getMessage());
System.exit(1);
}
// send Messages and finally release the resources.
try {
connection = connectionFactory.createConnection();
session = connection.createSession(Boolean.TRUE,
Session.SESSION_TRANSACTED);
producer = session.createProducer(destination); TextMessage message = session.createTextMessage();
for (int i = 0; i < 3; i++) {
message.setText(String.format("This is the %dth message.",
i + 1));
producer.send(message);
} if (isIntentional()) {
throw new JMSException("这是一个故意抛出的异常。");
} session.commit(); // 在最后提交
} catch (JMSException e) {
try {
session.rollback();
} catch (JMSException e1) {
e1.printStackTrace();
}
e.printStackTrace();
} finally {
try {
if (session != null)
session.close();
if (connection != null)
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
TransactedProducer.java
3.TransactedConsumer.java
package cn.sinobest.asj.consumer.jms.transaction;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.junit.Test;
/**
* 事务的接收者.<br>
* 测试接收正常和接收异常.
* @author lijinlong
*
*/
public class TransactedConsumer {
/** JNDI name for ConnectionFactory */
static final String CONNECTION_FACTORY_JNDI_NAME = "ConnectionFactory";
/** JNDI name for Queue Destination (use for PTP Mode) */
static final String QUEUE_JNDI_NAME = "exampleQueue"; /** 是否故意异常 */
boolean intentional = false; @Test
public void receiveNormal() {
intentional = false;
receive(QUEUE_JNDI_NAME);
} @Test
public void receiveIntentional() {
intentional = true;
receive(QUEUE_JNDI_NAME);
} /**
* 是否故意抛出异常,以检查消息的出队情况.
* @return
*/
private boolean isIntentional() {
return intentional;
} /**
* 接收消息.<br>
*
* @param destJndiName
* 目的地的JNDI name.
*/
private void receive(String destJndiName) {
Context jndiContext = null;
ConnectionFactory connectionFactory = null;
Connection connection = null;
Session session = null;
Destination destination = null;
MessageConsumer consumer = null;
// create a JNDI API IntialContext object
try {
jndiContext = new InitialContext();
} catch (NamingException e) {
System.out.println("Could not create JNDI Context:"
+ e.getMessage());
System.exit(1);
}
// look up ConnectionFactory and Destination
try {
connectionFactory = (ConnectionFactory) jndiContext
.lookup(CONNECTION_FACTORY_JNDI_NAME);
destination = (Destination) jndiContext.lookup(destJndiName);
} catch (NamingException e) {
System.out.println("JNDI look up failed:" + e.getMessage());
System.exit(1);
}
// receive Messages and finally release the resources.
try {
connection = connectionFactory.createConnection();
connection.start(); // connection should be called in
// receiver-client
session = connection.createSession(Boolean.TRUE,
Session.SESSION_TRANSACTED);
consumer = session.createConsumer(destination); long timeout = 5 * 1000; // timeout:5 seconds
for (Message message = consumer.receive(timeout); message != null; message = consumer.receive(timeout)) {
String text = ((TextMessage) message).getText();
System.out.println(text);
} if (isIntentional()) {
throw new JMSException("这是一个故意抛出的异常。");
} session.commit();
} catch (JMSException e) {
try {
session.rollback();
} catch (JMSException e1) {
e1.printStackTrace();
}
e.printStackTrace();
} finally {
try {
if (session != null)
session.close();
if (connection != null)
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
TransactedConsumer.java
AMQ学习笔记 - 17. 事务的测试的更多相关文章
- AMQ学习笔记 - 18. 持久化的测试
概述 对持久化的有效性进行测试. 测试实例 测试实例 结果预测 持久化递送 重启ActiveMQ后,消息还在队列中 非持久化递送 重启ActiveMQ后,消息不在队列中 demo设计 jms-prod ...
- CUBRID学习笔记17 事务的回滚
语法:ROLLBACK [ WORK ] 下面的语句会报错 ALTER TABLE code DROP s_name; INSERT INTO code (s_name, f_name) VALUES ...
- 软件测试之loadrunner学习笔记-01事务
loadrunner学习笔记-01事务<转载至网络> 事务又称为Transaction,事务是一个点为了衡量某个action的性能,需要在开始和结束位置插入一个范围,定义这样一个事务. 作 ...
- Ext.Net学习笔记17:Ext.Net GridPanel Selection
Ext.Net学习笔记17:Ext.Net GridPanel Selection 接下来是Ext.Net的GridPanel的另外一个功能:选择. 我们在GridPanel最开始的用法中已经见识过如 ...
- WCF学习笔记之事务编程
WCF学习笔记之事务编程 一:WCF事务设置 事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单元: WCF通过System.ServiceModel.TransactionFlowA ...
- SQL反模式学习笔记17 全文搜索
目标:全文搜索 使用SQL搜索关键字,同时保证快速和精确,依旧是相当地困难. SQL的一个基本原理(以及SQL所继承的关系原理)就是一列中的单个数据是原子性的. 反模式:模式匹配 使用Like 或者正 ...
- golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍
golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍 go语言爬虫框架:gocolly/colly,goquery,colly,chrom ...
- MySQL实战45讲学习笔记:事务隔离级别(第三讲)
一.隔离性与隔离级别 1.事务的特性 原子性 一致性 隔离性 持久性 2.不同事务隔离级别的区别 读未提交:别人改数据的事务尚未提交,我在我的事务中也能读到.读已提交:别人改数据的事务已经提交,我在我 ...
- AMQ学习笔记 - 06. 可靠消息传送
概述 本文介绍JMS中可能发生消息故障的3个隐患阶段,以及确保消息安全的3种保障机制. 故障分析 在介绍可靠传送的确保机制之前,先分析消息在传送的过程中可能在哪个阶段出现问题. 1.两个跃点 跃点的含 ...
随机推荐
- hdu 4828 Grids(拓展欧几里得+卡特兰数)
题目链接:hdu 4828 Grids 题目大意:略. 解题思路:将上一行看成是入栈,下一行看成是出栈,那么执着的方案就是卡特兰数,用递推的方式求解. #include <cstdio> ...
- HTML <base> 标签
定义和用法 <base> 标签为页面上的所有链接规定默认地址或默认目标. 通常情况下,浏览器会从当前文档的 URL 中提取相应的元素来填写相对 URL 中的空白. 使用 <base& ...
- JSAPI用户手册
本文档主要涵盖如何嵌入SpiderMonkey javascript引擎到你自己的c++程序中. JavaScript在浏览器端已经被广泛使用了.但是,Mozilla的javascript引擎可以被嵌 ...
- windows下搭建svn服务端、客户端
1.安装SVN服务器subversion以及客户端TortoiseSVN,在网上下载windows版的subversion,TortoiseSVN并安装,比如我的服务端安装在了D:\Program F ...
- jquery冲突
今天修改一个项目发现,前辈们自己写的一些方法和jquery冲突了,也就是$的冲突,以至于自己用jquery编写的新功能无法正常使用,细究后发现解决办法如下:使用 noConflict() 方法为 jQ ...
- 文件共享windows server 2008 服务器
1.远程连接到windows server2008 E盘右键共享 2.不能创建文件夹 右键E盘→共享→高级共享→权限→全部打勾即可. 3.ok,文件服务器
- C++11实现Qt的信号槽机制
概述 Qt的信号槽机制是Qt的核心机制,按钮点击的响应.线程间通信等都是通过信号槽来实现的,boost里也有信号槽,但和Qt提供的使用接口很不一样,本文主要是用C++11来实现一个简单的信号槽,该信号 ...
- html元素英文含义
常用html标签的英语全称及简单功能描述 <a>:anchor 定义锚 <abbr>:abbreviation 定义缩写 <acronym>: 定义只取消首字母的缩 ...
- Linux常用命令速查备忘
Linux常用命令速查备忘 PS:备忘而已,详细的命令参数说明自己man 一. 启动,关机,登入,登出相关命令 [login] 登录 [logout] 登出 [exit] 登出 [shutdown ...
- C Struct Hack
It's not clear if it's legal or portable, but it is rather popular. #include <stdlib.h> #inclu ...