概述


对事务机制进行测试。

测试实例


测试实例 结果预测
发送正常 3条消息入队
发送异常 0条消息入队
接收正常 3条消息出队
接收异常 0条消息出队

demo设计


设计图

测试分工

测试类 测试方法
TransactedProducer.java
- 测试发送
sendNormal():void
- 测试“发送正常”
sendIntentional():void
- 测试“发送异常”
TransactedConsumer.java
- 测试接收
receiveNormal():void
- 测试“接收正常”
receiveIntentional():void
- 测试“接收异常”

测试步骤和结果


1.测试发送

1.1.测试发送正常

测试步骤
  1. 在ActiveMQ管理页面,删除example.queue
    - 如果存在就删除
  2. 运行TransactedProducer#sendNormal()
    - 发送消息到example.queue
  3. 查看ActiveMQ管理页面
    - example.queue中有3条消息入队
测试结果
符合预期。

1.2.测试发送异常

测试步骤
  1. 在ActiveMQ管理页面,删除example.queue
    - 如果存在就删除
  2. 运行TransactedProducer#sendIntentional()
    - 发送消息到example.queue
  3. 查看控制台和ActiveMQ管理页面
    - 控制台有异常抛出
    - example.queue中入队消息0
测试结果
符合预期。

2.测试接收

2.1.测试接收正常

测试步骤
  1. 在ActiveMQ管理页面,删除example.queue
    - 如果存在就删除
  2. 运行TransactedProducer#sendNormal()
    - 发送消息到example.queue
  3. 查看ActiveMQ管理页面
    - example.queue中有3条消息入队
  4. 运行TransactedConsumer#receiveNormal()
    - 从example.queue中接收消息
  5. 查看控制台和ActiveMQ管理页面
    - 控制台打印出3条信息
    - 管理页面看到example.queue中的3条消息出队
测试结果
符合预期。

2.2.测试接收异常

测试步骤
  1. 在ActiveMQ管理页面,删除example.queue
    - 如果存在就删除
  2. 运行TransactedProducer#sendNormal()
    - 发送消息到example.queue
  3. 查看ActiveMQ管理页面
    - example.queue中有3条消息入队
  4. 运行TransactedConsumer#receiveIntentional()
    - 从example.queue中接收消息
  5. 查看控制台和ActiveMQ管理页面
    - 控制台打印出3条消息和异常信息
    - 管理页面看到example.queue中出队消息0条
测试结果
符合预期。

代码


文件目录结构

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. 事务的测试的更多相关文章

  1. AMQ学习笔记 - 18. 持久化的测试

    概述 对持久化的有效性进行测试. 测试实例 测试实例 结果预测 持久化递送 重启ActiveMQ后,消息还在队列中 非持久化递送 重启ActiveMQ后,消息不在队列中 demo设计 jms-prod ...

  2. CUBRID学习笔记17 事务的回滚

    语法:ROLLBACK [ WORK ] 下面的语句会报错 ALTER TABLE code DROP s_name; INSERT INTO code (s_name, f_name) VALUES ...

  3. 软件测试之loadrunner学习笔记-01事务

    loadrunner学习笔记-01事务<转载至网络> 事务又称为Transaction,事务是一个点为了衡量某个action的性能,需要在开始和结束位置插入一个范围,定义这样一个事务. 作 ...

  4. Ext.Net学习笔记17:Ext.Net GridPanel Selection

    Ext.Net学习笔记17:Ext.Net GridPanel Selection 接下来是Ext.Net的GridPanel的另外一个功能:选择. 我们在GridPanel最开始的用法中已经见识过如 ...

  5. WCF学习笔记之事务编程

    WCF学习笔记之事务编程 一:WCF事务设置 事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单元: WCF通过System.ServiceModel.TransactionFlowA ...

  6. SQL反模式学习笔记17 全文搜索

    目标:全文搜索 使用SQL搜索关键字,同时保证快速和精确,依旧是相当地困难. SQL的一个基本原理(以及SQL所继承的关系原理)就是一列中的单个数据是原子性的. 反模式:模式匹配 使用Like 或者正 ...

  7. golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍

    golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍 go语言爬虫框架:gocolly/colly,goquery,colly,chrom ...

  8. MySQL实战45讲学习笔记:事务隔离级别(第三讲)

    一.隔离性与隔离级别 1.事务的特性 原子性 一致性 隔离性 持久性 2.不同事务隔离级别的区别 读未提交:别人改数据的事务尚未提交,我在我的事务中也能读到.读已提交:别人改数据的事务已经提交,我在我 ...

  9. AMQ学习笔记 - 06. 可靠消息传送

    概述 本文介绍JMS中可能发生消息故障的3个隐患阶段,以及确保消息安全的3种保障机制. 故障分析 在介绍可靠传送的确保机制之前,先分析消息在传送的过程中可能在哪个阶段出现问题. 1.两个跃点 跃点的含 ...

随机推荐

  1. Linux中搭建SVNserver

    一 下载工具 1. subversion-1.6.17.tar.gz 2. subversion-deps-1.6.17.tar.gz 二 解压两个包: 1.在此之前,我已经创建了一个用户svnroo ...

  2. [Angular 2] Move and Delete Angular 2 Components After Creation

    After the original order is set, you can still leverage methods on the Angular 2 ViewContainer to re ...

  3. DES加密解密(适用Windows和Linux系统)防止linux下解密失败

    转自:http://blog.csdn.net/jerry_bj/article/details/8276552 package com.lasun.util; import java.io.File ...

  4. Spring MVC 3.0 请求转发和重定向

    首先看一下如何获得request对象.session对象: 普通的Controller类,示例代码如下: @Controller @RequestMapping(value = "user& ...

  5. IOS实用功能之截图(来自相册和拍照)

    // //  ViewController.m //  MyImagePicker1.0 // //  Created by Mac on 14-7-14. //  Copyright (c) 201 ...

  6. 《UCD火花集1-2》读后感

                                                                      一个多月的时间都没有更新博客了,只因为9月份有了其他的任务,耽搁了一 ...

  7. 基于CSS3图片可倾斜摆放的动画相册

    今天我们又要来分享一个CSS3动画相册.之前我们分享过一个很酷的放满女神的HTML5/CSS3相册,相册是全屏展示的.今天这款相册的特点是图片可以任意角度的倾斜摆放,就像随意放在桌面上一样.另外,当鼠 ...

  8. 记录一下bing的图片 - 升级版冰糖葫芦

    记录一下bing的图片 - 升级版冰糖葫芦

  9. LeetCode28 Implement strStr()

    题目: Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if ne ...

  10. 查找字符对应Unicode码的十进制数字

    //将字符转换为Unicode码中字符对应十进制数字 int byte0 = 'A' & 0xff;//byte0=65 参考文档:http://baike.baidu.com/view/26 ...