springcloud分布式事务Atomikos实例
0.JTA(Java Transaction Manager)的介绍
(1)jta与jdbc
简单的说 jta是多库的事务 jdbc是单库的事务
(2)XA与JTA
XA : XA是一个规范或是一个事务的协议.XA协议由Tuxedo首先提出的,并交给X/Open组织,作为资源管理器(数据库)与事务管理器的接口标准.
XA规范定义了:
1. TransactionManager : 这个TransactionManager可以通过管理多个ResourceManager来管理多个Resouce,也就是管理多个数据源
2. XAResource : 针对数据资源封装的一个接口
3. 两段式提交 : 多数据源事务提交的机制
JTA(Java Transaction Manager) : 是Java规范,是XA在Java上的实现.
1. TransactionManager : 常用方法,可以开启,回滚,获取事务. begin(),rollback()...
2. XAResouce : 资源管理,通过Session来进行事务管理,commit(xid)...
3. XID : 每一个事务都分配一个特定的XID
JTA是如何实现多数据源的事务管理呢?
主要的原理是两阶段提交,以上面的请求业务为例,当整个业务完成了之后只是第一阶段提交,在第二阶段提交之前会检查其他所有事务是否已经提交,如果前面出现了错误或是没有提交,那么第二阶段就不会提交,而是直接rollback操作,这样所有的事务都会做Rollback操作.
(3)jta特点
JTA的有点就是能够支持多数据库事务同时事务管理,满足分布式系统中的数据的一致性.但是也有对应的弊端:
- 两阶段提交
- 事务时间太长,锁数据太长
- 低性能,低吞吐量
1.maven的pom中增加spring-boot-starter-jta-atomikos
2.配置jta和atomikos的多数据源,例如:
jta: enabled: true atomikos: datasource: order: xa-properties.url: jdbc:h2:mem:dborder xa-properties.user: sa xa-properties.password: xa-data-source-class-name: org.h2.jdbcx.JdbcDataSource unique-resource-name: order max-pool-size: 10 min-pool-size: 1 max-lifetime: 10000 borrow-connection-timeout: 10000 log: xa-properties.url: jdbc:h2:mem:dblog xa-properties.user: sa xa-properties.password: xa-data-source-class-name: org.h2.jdbcx.JdbcDataSource unique-resource-name: log max-pool-size: 10 min-pool-size: 1 max-lifetime: 10000 borrow-connection-timeout: 10000
3.atomikos的jta与jpa的配置和数据源配置
import org.hibernate.engine.transaction.jta.platform.internal.AbstractJtaPlatform; import javax.transaction.TransactionManager; import javax.transaction.UserTransaction; /** * Created by caibosi on 2018-07-25. */ public class AtomikosJtaPlatform extends AbstractJtaPlatform { private static TransactionManager transactionManager; private static UserTransaction userTransaction; public static void setTransactionManager(TransactionManager transactionManager) { AtomikosJtaPlatform.transactionManager = transactionManager; } public static void setUserTransaction(UserTransaction userTransaction) { AtomikosJtaPlatform.userTransaction = userTransaction; } @Override protected TransactionManager locateTransactionManager() { return transactionManager; } @Override protected UserTransaction locateUserTransaction() { return userTransaction; } }
4.使用jta 在方法上面使用@Transactional
@Transactional public void newOrderRollback(String userId,String productCode,int quantity){ UserOrder userOrder = new UserOrder(); userOrder.setUserId(userId); userOrder.setProductCode(productCode); userOrder.setQuantity(quantity); userOrderDao.save(userOrder); EventLog eventLog = new EventLog(); eventLog.setOperation("new order"); eventLog.setOperator(userId); eventLogDao.save(eventLog); throw new RuntimeException("test jta rollback"); }
5.在调用newOrderRollback时会回滚
参考:https://github.com/SpringCloud/spring-cloud-code.git ch24
https://www.jianshu.com/p/3938e7172443