开发者社区> ~信~仰~> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

sharding-sphere中的xa事务

简介: Apache ShardingSphere 默认的 XA 事务管理器为 Atomikos。
+关注继续查看

Apache ShardingSphere 默认的 XA 事务管理器为 Atomikos。

j2ee对分布式事务定义了标准的规范,分别是JTA和JTS,JTA(Java Transaction API)是根据XA规范制定的java版本的接口规范,Atomikos就是jta的一种实现。JTA中约定了几种主要的程序角色:客户端、应用服务器、事务管理器、资源管理器。
JTA和JTS有什么关系呢?事务管理器要和资源管理器要进行事务上下文传播的交互,其中应用服务器和事务管理器之间也有传播事务上下文的交互,JTS就是定义各个程序角色之间如何传递事务上下文的规范。

JTA从框架的角度来约定实现者需要实现的接口,JTS约定了具体程序角色应该怎样去进行交互。

XA是X/Open CAE Specification (Distributed Transaction Processing)模型中定义的TM(Transaction Manager)与RM(Resource Manager)之间进行通信的接口。

在XA规范中,数据库充当RM角色,应用需要充当TM的角色,即生成全局的txId,调用XAResource接口,把多个本地事务协调为全局统一的分布式事务。

image.png

二阶段提交是XA的标准实现,它将分布式事务的提交拆分为2个阶段:prepare和commit/rollback。

开启XA全局事务后,所有子事务会按照本地默认的隔离级别锁定资源,并记录undo和redo日志,然后由TM发起prepare投票,询问所有的子事务是否可以进行提交。

当所有子事务反馈的结果为“yes”时,TM再发起commit;若其中任何一个子事务反馈的结果为“no”,TM则发起rollback。

如果在prepare阶段的反馈结果为yes,而commit的过程中出现宕机等异常时,则在节点服务重启后,可根据XA recover再次进行commit补偿,以保证数据的一致性。

XA recover的作用是列出所有处于PREPARE阶段的XA事务。

2PC模型中,在prepare阶段需要等待所有参与子事务的反馈,因此可能造成数据库资源锁定时间过长,不适合并发高以及子事务生命周长较长的业务场景。

Sharding-Sphere支持基于XA的强一致性事务解决方案,可以通过SPI注入不同的第三方组件作为事务管理器实现XA协议,如Atomikos和Narayana。

在sharding-sphere中默认使用了atomikos,编程时可以直接使用,例如注解方式为:

    @ShardingTransactionType(TransactionType.XA)
    @Transactional(rollbackFor = Exception.class)
    public void testTransactional() {
        User user1 = new User(1, "faith", 12);
        this.userDao.addOne(user1);
        User user2 = new User(2, "belief", 12);
        this.userDao.addOne(user2);
        this.userDao.addOne(user2); // 这里会报错,因为在分布式事务中,因此user1、user2都会插入失败
    }

如果spring项目中单独使用atomikos,需要做数据源以及事务管理器等配置,例如:

    <!-- 数据源 -->
    <bean id="abstractDatasource" abstract="true"
            class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
        <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
        <property name="poolSize" value="${datasource.poolSize}" />
        <property name="minPoolSize" value="${datasource.minPoolSize}" />
        <property name="maxPoolSize" value="${datasource.maxPoolSize}" />
        <!--获取连接失败重新获等待最大时间,在这个时间内如果有可用连接,将返回 -->
        <property name="borrowConnectionTimeout" value="60" />
        <!--最大获取数据时间,如果不设置这个值,Atomikos使用默认的5分钟,那么在处理大批量数据读取的时候,一旦超过5分钟,就会抛出类似 Resultset 
            is close 的错误. -->
        <property name="reapTimeout" value="20" />
        <!--最大闲置时间,超过最小连接池连接的连接将将关闭 -->
        <property name="maxIdleTime" value="${datasource.maxIdleTime}" />
        <!--连接回收时间 -->
        <property name="maintenanceInterval" value="60" />
        <!--java数据库连接池,最大可等待获取datasouce的时间 -->
        <property name="loginTimeout" value="60" />
        <property name="logWriter" value="60" />
        <!-- <property name="maxLifetime" value="1800000"/> -->
        <property name="testQuery">
            <value>select 1</value>
        </property>
    </bean>

    <!-- atomikos事务管理器 -->
    <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
        init-method="init" destroy-method="close">
        <description>UserTransactionManager</description>
        <property name="forceShutdown">
            <value>true</value>
        </property>
    </bean>

    <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
        <property name="transactionTimeout" value="300" />
    </bean>

    <!-- spring 事务管理器,包装了atomikos事务 -->
    <bean id="jtaTransactionManager"
        class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManager">
            <ref bean="atomikosTransactionManager" />
        </property>
        <property name="userTransaction">
            <ref bean="atomikosUserTransaction" />
        </property>
    </bean>

    <!-- spring 事务模板,和spring的jta事务类似功能 -->
    <bean id="transactionTemplate"
        class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager">
            <ref bean="jtaTransactionManager" />
        </property>
    </bean>

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
sharding-JDBC配置
水平分库和水平分表
193 0
Oracle Sharding
自从Oracle 12.2发布之后,Oracle数据库也可以实现分库分表,袋鼠云RDS基于Oracle12.2分库分表的功能,在产品上实现一键部署、智能运维、监控告警、备份恢复、性能管控等
2603 0
部署Sharding分片
这是一种将海量的数据水平扩展的数据库集群系统,数据分表存储在sharding 的各个节点上,使用者通过简单的配置就可以很方便地构建一个分布式MongoDB 集群。 MongoDB 的数据分块称为 chunk。
791 0
DNN Navisuite菜单模块原始XML文件的格式
DNN 比较好用的一个菜单模块式Navsuite模块,这个模块因为使用XML+XSL的技术手段,可以灵活的生成各种各样的菜单样式。 你可以通过修改style目录下的xsl文件来创建自己的菜单样式,但有一个问题是这个模块没有非常详细的手册,生成的XML是什么格式我们并不熟悉,我这里把生成的XML贴出来给大家参考。
510 0
DNN Navisuite菜单模块原始XML文件的格式
DNN 比较好用的一个菜单模块式Navsuite模块,这个模块因为使用XML+XSL的技术手段,可以灵活的生成各种各样的菜单样式。 你可以通过修改style目录下的xsl文件来创建自己的菜单样式,但有一个问题是这个模块没有非常详细的手册,生成的XML是什么格式我们并不熟悉,我这里把生成的XML贴出来给大家参考。
644 0
+关注
119
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载