Spring中怎么利用atomikos+druid实现分布式事务

今天就跟大家聊聊有关Spring中怎么利用atomikos+druid实现分布式事务,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

创新互联是一家集网站建设,莲都企业网站建设,莲都品牌网站建设,网站定制,莲都网站建设报价,网络营销,网络优化,莲都网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。

XA是啥?

XA是由X/Open组织提出的分布式事务的架构(或者叫协议)。XA架构主要定义了(全局)事务管理器(Transaction Manager)和(局部)资源管理器(Resource Manager)之间的接口。XA接口是双向的系统接口,在事务管理器(Transaction Manager)以及一个或多个资源管理器(Resource Manager)之间形成通信桥梁。也就是说,在基于XA的一个事务中,我们可以针对多个资源进行事务管理,例如一个系统访问多个数据库,或即访问数据库、又访问像消息中间件这样的资源。这样我们就能够实现在多个数据库和消息中间件直接实现全部提交、或全部取消的事务。XA规范不是java的规范,而是一种通用的规范,

目前各种数据库、以及很多消息中间件都支持XA规范。

JTA是满足XA规范的、用于Java开发的规范。所以,当我们说,使用JTA实现分布式事务的时候,其实就是说,使用JTA规范,实现系统内多个数据库、消息中间件等资源的事务。

JTA(Java Transaction API),是J2EE的编程接口规范,它是XA协议的JAVA实现。它主要定义了:

一个事务管理器的接口javax.transaction.TransactionManager,定义了有关事务的开始、提交、撤回等>操作。  一个满足XA规范的资源定义接口javax.transaction.xa.XAResource,一种资源如果要支持JTA事务,就需要让它的资源实现该XAResource接口,并实现该接口定义的两阶段提交相关的接口。如果我们有一个应用,它使用JTA接口实现事务,应用在运行的时候,就需要一个实现JTA的容器,一般情况下,这是一个J2EE容器,像JBoss,Websphere等应用服务器。但是,也有一些独立的框架实现了JTA,例如Atomikos, bitronix 都提供了jar包方式的JTA实现框架。这样我们就能够在Tomcat或者Jetty之类的服务器上运行使用JTA实现事务的应用系统。在上面的本地事务和外部事务的区别中说到,JTA事务是外部事务,可以用来实现对多个资源的事务性。它正是通过每个资源实现的XAResource来进行两阶段提交的控制。感兴趣的同学可以看看这个接口的方法,除了commit, rollback等方法以外,还有end(), forget(), isSameRM(), prepare()等等。光从这些接口就能够想象JTA在实现两阶段事务的复杂性。

本篇以Spring MVC+Maven+Atomikos+Druid+MyBatis演示分布式事务的实现。

Mave 的pom.xml

1.8 8.0.11 1.1.17 5.1.8.RELEASE 3.2.12 5.0.0 1.9.4 1.5.4 1.1 3.2.0 1.2.0 1.2.17 4.12 3.2.4 org.mybatis mybatis ${mybatise.version} org.mybatis mybatis-spring ${mybatis.spring} com.atomikos atomikos-util ${atomikos.version} com.atomikos transactions ${atomikos.version} com.atomikos transactions-jta ${atomikos.version} com.atomikos transactions-jdbc ${atomikos.version} com.atomikos transactions-api ${atomikos.version} javax.transaction jta ${jta.version} cglib cglib-nodep ${cglib.version} org.springframework spring-test ${spring.version} org.springframework spring-web ${spring.version} org.springframework spring-tx ${spring.version} org.springframework spring-beans ${spring.version} org.springframework spring-jdbc ${spring.version} org.springframework spring-webmvc ${spring.version} org.springframework spring-orm ${spring.version} org.springframework spring-context-support ${spring.version} org.aspectj aspectjweaver ${aspectjweaver.version} aspectj aspectjrt ${aspectjrt.version} cglib cglib ${cglib.version} mysql mysql-connector-java ${mysql.version} com.alibaba druid ${druid.version} junit junit ${junit.version} test

spring-application-context.xml

                               

spring-mybatis-atomikos-druid.xml

                        ${jdbc.driverClassName}        10  3  100    60000    60000    300000  SELECT 'x'  true  false  false    stat                          dataSourceOne                      ${jdbc.url}        ${jdbc.username}        ${jdbc.password}                          dataSourceTwo                      ${jdbc.two.url}        ${jdbc.two.username}        ${jdbc.two.password}                                                                                                                                                                                                              

jdbc.properties

#mysql 6.*以上jdbc.driverClassName = com.mysql.cj.jdbc.Driverjdbc.url = jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8&pinGlobalTxToPhysicalConnection=true&useSSL=falsejdbc.username =rootjdbc.password =rootjdbc.two.url = jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8&pinGlobalTxToPhysicalConnection=true&useSSL=falsejdbc.two.username =rootjdbc.two.password =root

jta.properties

com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactorycom.atomikos.icatch.console_file_name=tm.release.outcom.atomikos.icatch.log_base_name=tm.releaselogcom.atomikos.icatch.tm_unique_name=com.atomikos.spring.jdbc.tm.releasecom.atomikos.icatch.console_log_level=INFO

TestInsert.java

@ContextConfiguration(value = {"classpath:spring-application-context.xml"})@RunWith(SpringJUnit4ClassRunner.class)public class TestInsert { private Logger logger = LoggerFactory.getLogger(TestInsert.class); @Autowired private BatchInsertService batchInsertService; @Test public void insert(){  long startTime = System.currentTimeMillis(); User user = new User(); user.setName("User_"+(int)(Math.random()*100)); user.setAge((int)(Math.random()*100));  CustInfo info = new CustInfo(); info.setPhone("123456789"+(int)(Math.random()*100)); batchInsertService.insert(user,info);  long endTime = System.currentTimeMillis(); logger.info("共耗时:{}毫秒",endTime -startTime); }}

BatchInsertService.java

@Servicepublic class BatchInsertService { private Logger logger = LoggerFactory.getLogger(BatchInsertService.class); @Autowired private UserService userService; @Autowired private CustInfoService custInfoService; @Transactional(rollbackFor= {Exception.class,RuntimeException.class}) public void insert(User user,CustInfo custInfo) { int insertUser = userService.insert(user); logger.info("insertUser={}",insertUser); int insertCustInfo = custInfoService.insert(custInfo); logger.info("insertCustInfo={}",insertCustInfo); }}

UserService.java

@Servicepublic class UserService { @Autowired private UserMapper userMapper;  public int insert(User record) { int result = userMapper.insert(record); return result; } }

CustInfoService.java

@Servicepublic class CustInfoService { @Autowired private CustInfoMapper custInfoMapper; public int insert(CustInfo record) { int result = custInfoMapper.insert(record); long now = System.currentTimeMillis(); // 模拟一个异常 if (now % 2 == 0) {  throw new RuntimeException("CustInfoMapper throws test insert exception"); } return result; }}

看完上述内容,你们对Spring中怎么利用atomikos+druid实现分布式事务有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注创新互联行业资讯频道,感谢大家的支持。


本文题目:Spring中怎么利用atomikos+druid实现分布式事务
网页网址:http://myzitong.com/article/jhopgj.html