ShardingSphere 整合了XA、为分布式事务控制提供了极大的便利,我们可以在应用程序编程时,采用以下统一模式进行使用。
0 问题
当没有引入事务时,测试数据插入操作,并且在 i 等于4时,制造人为异常。
@Test
public void TestAdd(){
for (int i = 0; i < 20;) {
Orders orders = new Orders();
orders.setId(i++);
orders.setCustomer("张三" + i);
orders.setAmount((float) (Math.random() * 1000));
orders.setNumber((int)(Math.random() * 10));
orderRepository.save(orders);
if(i == 4){
throw new RuntimeException("人为异常!");
}
}
}
运行后,观察数据库,发现程序在运行在异常时,程序已经在库中插入了四条数据。
1 引入Maven依赖
在 pom.xml 文件中添加 XA 模式依赖的第三方库
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-transaction-xa-core</artifactId>
<version>4.1.1</version>
</dependency>
2 修改测试类
为测试方法添加 @Transactional 注解
设置事务类型为 XA,有两种方式,效果相同:
- 在方法中添加语句 TransactionTypeHolder.set(TransactionType.XA);
- 在方法前添加注解 @ShardingTransactionType(TransactionType.XA)
3 参数配置
对于复杂事务管理时,需要采用单独的配置文件来管理相关的配置项。
ShardingSphere 默认的XA事务管理器为 Atomikos,通过在项目的 classpath 中添加jta.properties 来定制化 Atomikos 配置项。具体的配置规则如下:
#指定是否启动磁盘日志,默认为true。 #在生产环境下一定要保证为true,否则数据的完整性无法保证
com.atomikos.icatch.enable_logging=true
#JTA/XA资源是否应该自动注册
com.atomikos.icatch.automatic_resource_registration=true
#JTA事务的默认超时时间,默认为10000ms
com.atomikos.icatch.default_jta_timeout=10000
#事务的最大超时时间,默认为300000ms。这表示事务超时时间由
#UserTransaction.setTransactionTimeout()较大者决定。4.x版本之后,指定为0的话则表示不设置超时时间
com.atomikos.icatch.max_timeout=300000
#指定在两阶段提交时,是否使用不同的线程(意味着并行)。3.7版本之后默认为false,更早的版本默认为true。如果为false,则提交将按照事务中访问资源的顺序进行。
com.atomikos.icatch.threaded_2pc=false
#指定最多可以同时运行的事务数量,默认值为50,负数表示没有数量限制。在调用 #UserTransaction.begin()方法时,可能会抛出一个”Max number of active transactionsreached”异常信息,表示超出最大事务数限制
com.atomikos.icatch.max_actives=50
#是否支持subtransaction,默认为true
com.atomikos.icatch.allow_subtransactions=true
#指定在可能的情况下,是否应该join子事务(subtransactions),默认值为true。如果设置为false,对于有关联的不同subtransactions,不会调用XAResource.start(TM_JOIN)
com.atomikos.icatch.serial_jta_transactions=true
#指定JVM关闭时是否强制(force)关闭事务管理器,默认为false
com.atomikos.icatch.force_shutdown_on_vm_exit=false
#在正常关闭(no-force)的情况下,应该等待事务执行完成的时间,默认为Long.MAX_VALUE
com.atomikos.icatch.default_max_wait_time_on_shutdown=9223372036854775807
========= 日志记录配置=======
#事务日志目录,默认为./。
com.atomikos.icatch.log_base_dir=./
#事务日志文件前缀,默认为tmlog。事务日志存储在文件中,文件名包含一个数字后缀,日志文件以.log为扩展名,如tmlog1.log。遇到checkpoint时,新的事务日志文件会被创建,数字增加。
com.atomikos.icatch.log_base_name=tmlog
#指定两次checkpoint的时间间隔,默认为500
com.atomikos.icatch.checkpoint_interval=500
=========日志恢复配置=============
#指定在多长时间后可以清空无法恢复的事务日志(orphaned),默认86400000ms
com.atomikos.icatch.forget_orphaned_log_entries_delay=86400000
#指定两次恢复扫描之间的延迟时间。默认值为与#com.atomikos.icatch.default_jta_timeout相同
com.atomikos.icatch.recovery_delay=${com.atomikos.icatch.default_jta_timeout}
#提交失败时,再抛出一个异常之前,最多可以重试几次,默认值为5
com.atomikos.icatch.oltp_max_retries=5
#提交失败时,每次重试的时间间隔,默认10000ms
com.atomikos.icatch.oltp_retry_interval=10000
4 重新执行测试方法
执行修改后的测试方法,当程序在运行到异常时,进行了回滚操作。
观察数据库,所有数据都没有被插入。