ShardingJDBC 15_分布式事务实战

168 阅读3分钟

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);

image.png

  • 在方法前添加注解 @ShardingTransactionType(TransactionType.XA)

image.png

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 重新执行测试方法

执行修改后的测试方法,当程序在运行到异常时,进行了回滚操作。

观察数据库,所有数据都没有被插入。

image.png