JTA + Atomikos + Druid 分布式事务源码图解

入口: 根据前一篇文章,得知入口是 TransactionInterceptor
XA 规范说明:
    对多个数据源操作
    d1:
        1) d1XAResource.start: xa事务准备
        2) d1.prepareStatement    sql拼接以及sql执行,不commit
        3) d1XAResource.end    xa事务准备完成
      
    d2:
        1) d2XAResource.start: xa事务准备
        2) d2.prepareStatement    sql拼接以及sql执行,不commit
        3) d2XAResource.end    xa事务准备完成
   

        4) d1XAResource.prepare   
        5) d2XAResource.prepare   
        6) d1XAResource.commit    commit
        7) d2XAResource.commit    commit

Mysql对XA事务支持:
    XA {START|BEGIN} xid [JOIN|RESUME]   //开启XA事务,如果使用的是XA START而不是XA BEGIN,那么不支持[JOIN|RESUME],xid是一个唯一值,表示事务分支标识符
    XA END xid [SUSPEND [FOR MIGRATE]]   //结束一个XA事务,不支持[SUSPEND [FOR MIGRATE]]
    XA PREPARE xid 准备提交
    XA COMMIT xid [ONE PHASE] //提交,如果使用了ONE PHASE,则表示使用一阶段提交。两阶段提交协议中,如果只有一个RM参与,那么可以优化为一阶段提交
    XA ROLLBACK xid  //回滚
    XA RECOVER [CONVERT XID]  //列出所有处于PREPARE阶段的XA事务
 
    1.1 TransactionInterceptor.invokeWithinTransaction
        1.1.1 invokeWithinTransaction.createTransactionIfNecessary 
            为每一个数据库操作创建一个子事务(基于动态代理,所以方法必须是public)
        1.1.2 invokeWithinTransaction#invocation.proceedWithInvocation()
            a、具体的业务代码执行,sql会执行,开启读未提交,在此阶段执行完成之后,可以看到数据
            b、会对每个子事务进行 XAResource.start操作,会到mysql中执行start指令,标志分布式事务开启
        1.1.3 invokeWithinTransaction.commitTransactionAfterReturning
            1.1.3.1 AbstractPlatformTransactionManager.commit
                1.1.3.1.1 AbstractPlatformTransactionManager.triggerBeforeCompletion    
                    对每个子事务进行 XAResource.end操作,会到mysql中执行end指令,标志分布式事务结束
                1.1.3.1.2 JTATransactionManager.doCommit        
                    1.1.3.1.2.1 CoordinatorImp
                    最重要的逻辑判断,实现了
                    XAResource.prepare,即sql执行,如果prepare阶段报错了,则进行rollback,如果prepare阶段成功看了,则commit
                    会到mysql中执行prepare指令,通知mysql我要提交事务了,给我准备好资源
                    会到mysql中执行commit指令, 提交事务
                    synchronized ( fsm_ ) {
    		            if ( commit ) {
    			            if ( participants_.size () <= 1 ) {
    				            commit ( true );
    			            } else {
    				            int prepareResult = prepare ();
    				            if ( prepareResult != Participant.READ_ONLY )
    					            commit ( false );
    			                }
    		                } else {
    			                rollback ();
    		                }
    	                }

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring+iBatis+JOTM实现JTA事务: 如何处理跨库事物:spring + jtom 的jta事务是个很好的选择. 这个源码示例非常不错,包括所有的源码和jar包,下载后eclipse 或 myeclipse 导入就能用。 里面有详细的说明和注释,欢迎下载传播。有问题请在评价中留言,我会及时回复的。 <bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/> <!-- JTA事务管理器 --> <bean id="myJtaManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="userTransaction"> <ref local="jotm"/> </property> </bean> <!-- 数据源A --> <bean id="dataSourceA" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown"> <property name="dataSource"> <bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown"> <property name="transactionManager" ref="jotm"/> <property name="driverName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> </bean> </property> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!-- 数据源B --> <bean id="dataSourceB" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown"> <property name="dataSource"> <bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown"> <property name="transactionManager" ref="jotm"/> <property name="driverName" value="${jdbc2.driver}"/> <property name="url" value="${jdbc2.url}"/> </bean> </property> <property name="user" value="${jdbc2.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!-- 事务切面配置 --> <aop:config> <aop:pointcut id="serviceOperation" expression="execution(* *..servi1ce*..*(..))"/> <aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice"/> </aop:config> <!-- 通知配置 --> <tx:advice id="txAdvice" transaction-manager="myJtaManager"> <tx:attributes> <tx:method name="delete*" rollback-for="Exception"/> <tx:method name="save*" rollback-for="Exception"/> <tx:method name="update*" rollback-for="Exception"/> <tx:method name="*" read-only="true" rollback-for="Exception"/> </tx:attributes> </tx:advice ...... ...... ......

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值