ActiveMQ完全遵循jms规范,而jms是支持事务的,即要么全部成功,要么全部失败。很多时间,我们的JMS操作需要和数据库操作的事务一致,即要么jms和数据库操作都成功,要么jms和数据库操作都失败,这就是分布式事务(xa事务, 也就是所谓的两段式提交事务,在java中的编程接口为JTA)的用武之地。
完美实现j2ee规范的web server是提供对JTA的实现的,但是tomcat,jetty等轻量级的web server没有提供,在j2se环境也没有,幸运的是还有第三的实现。atomikos就是其中的一个,因其有完整的文档,活跃的社区,商业的支持,而成为第三方jta实现的佼佼者。本文就使用该实现来实践xa事务。
步骤:
为了让本demo有最大的可移植性,本文使用h2数据库,而h2虽然是嵌入式数据库,但是它实现了xa事务,这正是我需要的。
1、新建一个Maven 工程
2、在Pom.Xml中添加对应的依赖
主要有spring-jms,spring-jdbc,activemq-all,com.atomikos:transactions-jta,com.atomikos:transactions-jdbc,com.atomikos:transactions-jms,com.h2database:h2
3、新建Schema.Sql,用于创建测试用的表
|
DROPTABLEIF EXISTStest_user;
createtabletest_user(
usernamevarchar(32),
passwordvarchar(32),
emailvarchar(32),
phonevarchar(11),
sexchar(1),
primary key(email)
);
|
4、新建ApplicationContext.Xml
配置对应的bean,具体可以参考附件中的对应文件,注意xa.dataSource和xa.connectionFactory bean的定义,都指定了init-method="init" destroy-method="close"属性,因为在init方法中会将其加入Transaction Manager中去。
2)为了便于管理h2数据库,我声明了org.h2.tools.Server ,这样就可以将浏览器指向http://localhost:8082/来查看h2数据库的内容。
5、开发Service类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
publicclassTestXaService{
@Autowired
JdbcTemplate jdbcTemplate;
@Autowired
JmsTemplate jmsTemplate;
@Transactional(readOnly=false,rollbackFor={JdbcSQLException.class,RuntimeException.class})
publicvoidpersistence(List<User>list){
for(User user:list){
this.insertBatch(user);
this.send_amq(user);
}
}
publicvoidinsertBatch(User user){
Stringsql="insert into test_user(username, password, email, phone,sex) values ";
Stringpattern=" ('%s', '%s', '%s', '%s', '%c') ";
sql+=String.format(pattern,user.getUsername(),user.getPassword(),
user.getEmail(),user.getPhone(),user.getSex());
System.out.println(sql);
jdbcTemplate.execute(sql);
}
publicvoidsend_amq(finalUser user){
jmsTemplate.send("test.queue",newMessageCreator(){
publicMessage createMessage(Session session)throwsJMSException{
returnsession.createObjectMessage(user);
}
});
}
}
|
代码很简单,将User对象同时插入数据库和ActiveMQ队列。只要有某一步操作异常,就会造成数据库和ActiveMQ操作都回滚。使用了Spring经典的声明式事务@Transactional,当发生JdbcSQLException或者RuntimeException时回滚。
6、添加Main方法来触发测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
publicstaticvoidmain(String[]args){
User user=newUser();
user.setEmail("javacoder.cn@hotmail.com");
user.setPassword("123456");
user.setPhone("123456");
user.setSex('M');
user.setUsername("javacoder.cn");
User user1=newUser();
user1.setEmail("rex173505@gmail.com");
user1.setPassword("123456");
user1.setPhone("123456");
user1.setSex('M');
user1.setUsername("javacoder.cn");
ApplicationContext context=newClassPathXmlApplicationContext(
"classpath:applicationContext.xml");
List<User>list=newArrayList<User>();
list.add(user);
list.add(user1);
list.add(user);//让数据库报主键重复的异常
TestXaService testXaService=(TestXaService)context.getBean("testXaService");
testXaService.persistence(list);
System.out
.println("send successfully, please visit http://localhost:8161/admin to see it");
}
|
代码很简单,我们构造了两个User对象,注意我们将user 两次加入到了list中,目的为了造成主键重复!!
从context中获取TestXaService对象,调用testXaService.persistence(list)来持久化该list中的对象。
7、测试:
1、启动ActiveMQ 服务器
2、运行程序,发现插入失败,ActiveMQ事务和数据库事务都回滚;将user对象只插入一次到list中,事务提交成功。
参考文档:
1、《ActiveMQ in action》
2、Configuring ActiveMQ transactions in Spring
3、atomikos官网
4、Atomikos TransactionsEssentials Guide.pdf
http://www.javacoder.cn/?p=428
分享到:
相关推荐
spring+druid+atomikos分布式事务,多数据源切换!其中包括配置文件
测试atomikos spring activemq jta oracle 为了最大限度地恢复和关闭/重启能力,强烈建议您使用以下 init 依赖项配置 Spring 配置: 使事务管理器依赖于您所有的 JDBC 和 JMS 连接工厂:这可确保在关闭期间事务管理...
基于若依项目改造的多模块分布式事务,使用了atomikos进行分布式事务的管理。
NULL 博文链接:https://tws502934462.iteye.com/blog/1186912
atomikos jar,spring 分布式事务提交框架
SpringBoot+Atomikos+动态多数据源+事务+2种切换数据源的方式 SpringBoot+Atomikos+动态多数据源+事务+2种切换数据源的方式
基于XA的非Maven 基于SpringMVC+Spring+MyBatis+Atomikos的分布式事务处理案例源码,亲自测试可以使用。能SSM多数据源环境和分布式环境下事务处理问题.
Spring boot+Atomikos+JTA+Hibernate+MySQL实现分布式事务+多数据源,分别向两个不同的数据里面插入数据同时失败和成功,调用接口方式原理一样。
这个一个activemq服务项目,内有activemq事务,集群,我在里面作了一个spring的事务,Atomikos的事务相应jar包。希望大家下载给出建议,(我在做这个时花了很长的时间,下载其他的文件也花了很多时间,所以在下载时,...
spring+hibernate+atomikos实现多数据源分布式事务管理
将基于Spring4.1.7+atomikos+mybaits 实现两阶段的分布式事务处理,通过AOP面向切面实现动态实现数据源的切换 http://www.dczou.com/viemall/407.html
使用spring + atomikos+druid配置的分布式事务demo,两种数据源配置方式都可以,使用junit测试没问题,案例中使用的mysql数据库是8.0.11版本,版本不同请自行修改pom.xml和jdbc.properties
spring + JTA + atomikos实现分布式事务, 高大上的技术
spring+druid+AtomikosDataSource实现多数据源切换及分布式事务控制
开发工具:MyEclipse10, 数据库:Mysql, demo中使用了2个数据源,2个不同的Mysql数据库。 注:不同数据库dataSource的配置是不一样的
spring mybatis atomikos 分布式事务 自己写的小demo 包含依赖包
本文整合了一个spring和atomikos的demo,并且通过案例演示说明atomikos的作用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
基于Spring4.1.7+atomikos+mybaits 实现两阶段的分布式事务处理
SpringBoot+Atomikos分布式事务及多数据源动态切换,两种demo,两条数据源,是满足事务唯一性的,看清楚是demo