400 028 6601

建站动态

根据您的个性需求进行定制 先人一步 抢占小程序红利时代

Spring中使用atomikos+druid实现经典分布式事务的方法

经典分布式事务,是相对互联网中的柔性分布式事务而言,其特性为ACID原则,包括原子性(Atomictiy)、一致性(Consistency)、隔离性(Isolation)、持久性(Durabilit):

芒市ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18980820575(备注:SSL证书合作)期待与您的合作!

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实现。它主要定义了:

本篇以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

<?xml version="1.0" encoding="UTF-8"?>

  
   
  
 
 
 
  
  
  
  
  
  
   
    
   
  
  
  

spring-mybatis-atomikos-druid.xml

<?xml version="1.0" encoding="UTF-8"?>
  

 
 
  
    
    
      
       ${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.Driver
jdbc.url = jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8&pinGlobalTxToPhysicalConnection=true&useSSL=false
jdbc.username =root
jdbc.password =root

jdbc.two.url = jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8&pinGlobalTxToPhysicalConnection=true&useSSL=false
jdbc.two.username =root
jdbc.two.password =root

jta.properties

com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory
com.atomikos.icatch.console_file_name=tm.release.out
com.atomikos.icatch.log_base_name=tm.releaselog
com.atomikos.icatch.tm_unique_name=com.atomikos.spring.jdbc.tm.release
com.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

@Service
public 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

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

CustInfoService.java

@Service
public 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;
 }
}

Mapper和Bean等就不列出来了,完成的示例工程在github: https://github.com/fenglibin/DruidWithAtomikos

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持创新互联。


当前名称:Spring中使用atomikos+druid实现经典分布式事务的方法
链接地址:http://mbwzsj.com/article/ghpdcp.html

其他资讯

让你的专属顾问为你服务