`

关于分布式事务

阅读更多

 

 

Mysql当前分布式事务只支持Innodb存储引擎。1个分布式事务由多个行为在不同的数据库上执行,1个分布式事务的执行成功意味着相关数据库上的行为执行均成功。

使用分布式事务的应用程序设计1个或多个资源管理器和一个事务管理器。
资源管理器(RM):用户提供通向事务的途径。数据库服务器是一个种资源管理器。该管理器必须提交or回滚由RM管理的事务。
事务管理器(TM):用于协调作为一个分布式事务的一部分事务。

要执行一个分布式事务,必须知道这个分布式事涉及了哪些资源管理器,并且把每个资源管理器的事务执行到事务可以被提交或回滚。根据每个资源管理报告的有关的执行情况的内容,这些分支事务必须作为一个原子性操作全部提交或回滚。

用于执行分布式事务的过程使用两阶段提交,发生时间在由分布式事务的各个分支需要进行的行动已经被执行之后。
 
在第一阶段,所有的分支都预备好。他们被TM告知要准备提交。用于管理分支的每个RM会记录对于被稳定保存的分支的行动。分支指示是否他们可以这么做。这些结果被用于第二阶段。
 

在第二阶段,TM告知RMs是否要提交或回滚。如果在预备分支时,所有的分支指示他们将能够提交,则所有的分支被告知要提交。如果在预备时,有任何分支指示它将不能提交,则所有分支被告之回滚。

分布式的语法:
XA START xid ,用来唯一标识一个分布式事务。
XA END xid
XA PRERARE xid
XA COMMIT xid
XA ROLLBACK xid
XA RECOVER



 

 

--------------------分布式事务详解--------------------------

  分布式事务是指操作多个数据库之间的事务,spring的org.springframework.transaction.jta.JtaTransactionManager,提供了分布式事务支持。如果使用WAS的JTA支持,把它的属性改为WebSphere对应的TransactionManager。 
       在tomcat下,是没有分布式事务的,不过可以借助于第三方软件jotm(Java Open Transaction Manager )和AtomikosTransactionsEssentials实现,在spring中分布式事务是通过jta(jotm,atomikos)来进行实现。 
1、http://jotm.objectweb.org/ 
2、http://www.atomikos.com/Main/TransactionsEssentials 

一、使用JOTM例子 
(1) Dao及实现 

GenericDao接口:

  1. public interface GenericDao {  
  2.     public int save(String ds, String sql, Object[] obj) throws Exception;    
  3.     public int findRowCount(String ds, String sql);   
  4. }  

GenericDaoImpl 实现:

  1. public class GenericDaoImpl implements GenericDao{  
  2.   
  3.     private  JdbcTemplate jdbcTemplateA;  
  4.     private  JdbcTemplate jdbcTemplateB;  
  5.   
  6.     public void setJdbcTemplateA(JdbcTemplate jdbcTemplate) {  
  7.         this.jdbcTemplateA = jdbcTemplate;  
  8.     }  
  9.   
  10.     public void setJdbcTemplateB(JdbcTemplate jdbcTemplate) {  
  11.         this.jdbcTemplateB = jdbcTemplate;  
  12.     }  
  13.       
  14.     public int save(String ds, String sql, Object[] obj) throws Exception{  
  15.         if(null == ds || "".equals(ds)) return -1;  
  16.         try{  
  17.             if(ds.equals("A")){  
  18.                 return this.jdbcTemplateA.update(sql, obj);  
  19.             }else{  
  20.                 return this.jdbcTemplateB.update(sql, obj);  
  21.             }  
  22.         }catch(Exception e){  
  23.             e.printStackTrace();  
  24.             throw new Exception("执行" + ds + "数据库时失败!");  
  25.         }  
  26.     }  
  27.   
  28.     public int findRowCount(String ds, String sql) {  
  29.         if(null == ds || "".equals(ds)) return -1;  
  30.           
  31.         if(ds.equals("A")){  
  32.             return this.jdbcTemplateA.queryForInt(sql);  
  33.         }else{  
  34.             return this.jdbcTemplateB.queryForInt(sql);  
  35.         }  
  36.     }  
  37. }  

 

(2) Service及实现 

UserService 接口:

  1. public interface UserService {  
  2.     public void saveUser() throws Exception;  
  3. }  

UserServiceImpl 实现:

  1. public class UserServiceImpl implements UserService{  
  2.   
  3.     private GenericDao genericDao;  
  4.       
  5.     public void setGenericDao(GenericDao genericDao) {  
  6.         this.genericDao = genericDao;  
  7.     }  
  8.   
  9.     public void saveUser() throws Exception {  
  10.         String userName = "user_" + Math.round(Math.random()*10000);  
  11.         System.out.println(userName);  
  12.           
  13.         StringBuilder sql = new StringBuilder();  
  14.         sql.append(" insert into t_user(username, gender) values(?,?); ");  
  15.         Object[] objs = new Object[]{userName,"1"};  
  16.           
  17.         genericDao.save("A", sql.toString(), objs);  
  18.           
  19.         sql.delete(0, sql.length());  
  20.         sql.append(" insert into t_user(name, sex) values(?,?); ");  
  21.         objs = new Object[]{userName,"男的"};//值超出范围  
  22.         genericDao.save("B", sql.toString(), objs);  
  23.     }  
  24. }  

 

(3) applicationContext-jotm.xml

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"   
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  4.     xmlns:context="http://www.springframework.org/schema/context"   
  5.     xmlns:aop="http://www.springframework.org/schema/aop"   
  6.     xmlns:tx="http://www.springframework.org/schema/tx"   
  7.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd   
  8.     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd   
  9.     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd   
  10.     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">  
  11.   
  12.     <description>springJTA</description>  
  13.   
  14.     <!--指定Spring配置中用到的属性文件-->   
  15.     <bean id="propertyConfig"   
  16.             class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">   
  17.         <property name="locations">   
  18.             <list>   
  19.                 <value>classpath:jdbc.properties</value>   
  20.             </list>   
  21.         </property>   
  22.     </bean>   
  23.       
  24.     <!-- JOTM实例 -->  
  25.     <bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean">  
  26.           <property name="defaultTimeout" value="500000"/>  
  27.     </bean>  
  28.   
  29.     <!-- JTA事务管理器 -->  
  30.     <bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">     
  31.         <property name="userTransaction" ref="jotm" />     
  32.     </bean>  
  33.   
  34.     <!-- 数据源A -->   
  35.     <bean id="dataSourceA" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">   
  36.        <property name="dataSource">   
  37.            <bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">   
  38.                <property name="transactionManager" ref="jotm"/>   
  39.                <property name="driverName" value="${jdbc.driver}"/>   
  40.                <property name="url" value="${jdbc.url}"/>   
  41.            </bean>   
  42.        </property>   
  43.        <property name="user" value="${jdbc.username}"/>   
  44.        <property name="password" value="${jdbc.password}"/>   
  45.     </bean>   
  46.   
  47.     <!-- 数据源B -->   
  48.     <bean id="dataSourceB" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">   
  49.        <property name="dataSource">   
  50.            <bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">   
  51.                <property name="transactionManager" ref="jotm"/>   
  52.                <property name="driverName" value="${jdbc2.driver}"/>   
  53.                <property name="url" value="${jdbc2.url}"/>   
  54.            </bean>   
  55.        </property>   
  56.        <property name="user" value="${jdbc2.username}"/>   
  57.        <property name="password" value="${jdbc2.password}"/>   
  58.     </bean>   
  59.   
  60.     <bean id = "jdbcTemplateA"   
  61.          class = "org.springframework.jdbc.core.JdbcTemplate">   
  62.          <property name = "dataSource" ref="dataSourceA"/>   
  63.     </bean>  
  64.       
  65.     <bean id = "jdbcTemplateB"   
  66.          class = "org.springframework.jdbc.core.JdbcTemplate">   
  67.          <property name = "dataSource" ref="dataSourceB"/>   
  68.     </bean>      
  69.   
  70.     <!-- 事务切面配置 -->   
  71.     <aop:config>   
  72.         <aop:pointcut id="pointCut"  
  73.                 expression="execution(* com.logcd.service..*.*(..))"/><!-- 包及其子包下的所有方法 -->  
  74.         <aop:advisor pointcut-ref="pointCut" advice-ref="txAdvice"/>   
  75.           
  76.         <aop:advisor pointcut="execution(* *..common.service..*.*(..))" advice-ref="txAdvice"/>  
  77.     </aop:config>   
  78.   
  79.     <!-- 通知配置 -->   
  80.     <tx:advice id="txAdvice" transaction-manager="jtaTransactionManager">   
  81.        <tx:attributes>   
  82.           <tx:method name="delete*" rollback-for="Exception"/>   
  83.           <tx:method name="save*" rollback-for="Exception"/>   
  84.           <tx:method name="update*" rollback-for="Exception"/>   
  85.           <tx:method name="find*" read-only="true" rollback-for="Exception"/>   
  86.        </tx:attributes>   
  87.     </tx:advice>   
  88.   
  89.     <bean id="genericDao"  class="com.logcd.dao.impl.GenericDaoImpl" autowire="byName"> </bean>  
  90.     <bean id="userService"  class="com.logcd.service.impl.UserServiceImpl" autowire="byName"> </bean>  
  91. </beans>  

 

(4) 测试

  1. public class TestUserService{  
  2.   
  3.     private static UserService userService;  
  4.       
  5.     @BeforeClass  
  6.     public static void init(){  
  7.         ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext-jotm.xml");  
  8.         userService = (UserService)app.getBean("userService");  
  9.     }  
  10.       
  11.     @Test  
  12.     public void save(){  
  13.         System.out.println("begin...");  
  14.         try{  
  15.             userService.saveUser();  
  16.         }catch(Exception e){  
  17.             System.out.println(e.getMessage());  
  18.         }  
  19.         System.out.println("finish...");  
  20.     }  
  21. }  



二、关于使用atomikos实现 
(1) 数据源配置

  1. <bean id="dataSourceA" class="com.atomikos.jdbc.SimpleDataSourceBean" init-method="init" destroy-method="close">  
  2.     <property name="uniqueResourceName">  
  3.         <value>${datasource.uniqueResourceName}</value>  
  4.     </property>  
  5.     <property name="xaDataSourceClassName">   
  6.         <value>${database.driver_class}</value>   
  7.     </property>   
  8.     <property name="xaDataSourceProperties">  
  9.         <value>URL=${database.url};user=${database.username};password=${database.password}</value>   
  10.     </property>   
  11.     <property name="exclusiveConnectionMode">   
  12.         <value>${connection.exclusive.mode}</value>   
  13.     </property>  
  14.     <property name="connectionPoolSize">   
  15.         <value>${connection.pool.size}</value>  
  16.     </property>  
  17.     <property name="connectionTimeout">  
  18.         <value>${connection.timeout}</value>  
  19.     </property>  
  20.     <property name="validatingQuery">   
  21.         <value>SELECT 1</value>   
  22.     </property>   
  23. </bean>  


(2)、事务配置

  1. <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"   
  2.     init-method="init" destroy-method="close">   
  3.     <property name="forceShutdown" value="true"/>   
  4. </bean>   
  5.   
  6. <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">   
  7.     <property name="transactionTimeout" value="${transaction.timeout}"/>   
  8. </bean>  
  9.   
  10. <!-- JTA事务管理器 -->   
  11. <bean id="springTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">   
  12.     <property name="transactionManager" ref="atomikosTransactionManager"/>   
  13.     <property name="userTransaction" ref="atomikosUserTransaction"/>   
  14. </bean>  
  15.   
  16. <!-- 事务切面配置 -->   
  17. <aop:config>   
  18.     <aop:pointcut id="serviceOperation"  expression="execution(* *..service*..*(..))"/>   
  19.     <aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice"/>   
  20. </aop:config>  
  21.   
  22. <!-- 通知配置 -->  
  23. <tx:advice id="txAdvice" transaction-manager="springTransactionManager">   
  24.     <tx:attributes>  
  25.         <tx:method name="*" rollback-for="Exception"/>   
  26.     </tx:attributes>   
  27. </tx:advice>   



有关JTA
JTA全称为Java Transaction API,顾名思义JTA定义了一组统一的事务编程的接口,这些接口如下:
 
XAResource 
XAResource接口是对实现了X/Open CAE规范的资源管理器 (Resource Manager,数据库就是典型的资源管理器) 的抽象,它由资源适配器 (Resource Apdater) 提供实现。XAResource是支持事务控制的核心。

Transaction
Transaction接口是一个事务实例的抽象,通过它可以控制事务内多个资源的提交或者回滚。二阶段提交过程也是由Transaction接口的实现者来完成的。

TransactionManager
托管模式 (managed mode) 下,TransactionManager接口是被应用服务器调用,以控制事务的边界的。
 
UserTransaction
非托管模式 (non-managed mode) 下,应用程序可以通过UserTransaction接口控制事务的边界
 
托管模式下的事务提交场景



 

注意:在上图中3和5的步骤之间省略了应用程序对资源的操作 (如CRUD)。另外,应用服务器什么时机 enlistResource,又是什么时候delistResource呢?这在后文中会解释。

 

有关JCA

下图为JCA的架构图



 

中间涉及元素说明如下:
1)Enterprise Information System
简称EIS,在JTA中它又被称为资源管理器。典型的EIS有数据库,事务处理系统(Transaction Processing System),ERP系统。
 
2)Resource Adapter
资源适配器(Resource Adaper)是JCA的关键。要想把不同的EIS整合(或者连接)到J2EE运行环境中,就必须为每个EIS提供资源适配器,它会将将EIS适配为一个具备统一编程接口的资源 (Resource) 。这个统一编程接口就是上图中的System Contracts和Client API。下面的UML类图将完美诠释资源适配器。

 

3)Application Server
应用服务器 (Application Server) 通过System Contracts来管理对EIS的安全、事务、连接等。典型的应用服务器有JBoss、JOnAS、Geronimo、GlassFish等。
 
4)Application Component 
应用组件 (Application Component) ,它封装了应用业务逻辑,像对资源的访问和修改。典型的应用组件就是EJB。
 
更多细节请参见:
Sun Microsystems Inc.J2EE Connector Architecture 1.5 

 

 

http://www.ibm.com/developerworks/cn/java/j-lo-jta/

http://blog.csdn.net/ithomer/article/details/10859235

http://liuhaodba.blog.51cto.com/6379925/1117647

http://hedengcheng.com/?p=136

  • 大小: 76.2 KB
  • 大小: 38.3 KB
  • 大小: 27.2 KB
分享到:
评论

相关推荐

    微服务架构的分布式事务解决方案(Dubbo分布式事务处理)

    为了解决大家在实施分布式服务化架构过程中关于分布式事务问题的困扰,本教程将基于支付系统真实业务中的经典场景来对“可靠消息的最终一致性方案”、“TCC两阶段型方案”和“最大努力通知型方案”这3种柔性事务解决...

    关于分布式事务的整理

    分布式、事务、常用解决方案、案例分析

    某果 - 微服务架构的分布式事务解决方案.txt

    为了解决大家在实施分布式服务化架构过程中关于分布式事务问题的困扰,本教程将基于支付系统真实业务中的经典场景来对“可靠消息的最终一致性方案”、“TCC两阶段型方案”和“最大努力通知型方案”这3种柔性事务解决...

    关于分布式事务.docx

    针对消费失败这种情况,最好的办法就是通过报警系统及时发现失败情况然后再人工处理。其实为了交易系统更可靠,我们一般会在类似交易这种高级别的服务代码中,加入详细日志记录的,一旦系统内部引发类似致命异常要...

    事务处理API分布式事务处理

    本文的目的是要提供一个关于的Java事务处理API(JTA)的高级的概述,以及与分布式事务相关的内容。一个事务处理定义了一个工作逻辑单元,要么彻底成功要么不产生任何结果。 一个分布式事务处理只是一个在两个或更多...

    分布式事务视频教程,绝对不加密版本,附加课件

    这事关于分布式事务的处理视频教程,内容很详细,网上绝大多数都要解压码,这个视频教程是本人在某宝商花重金购买的哦,绝对不加密,而且里面还包含相关的课件。

    ejb3.0 分布式事务

    关于ejb3.0 分布式事务的demo,涉及到相关persistence.xml 配置以及数据源配置。

    分布式事务的并发控制

    这是一节关于研究生研一分布式设计课程中的课件,里面的内容是关于分布式事务的并发控制。

    DotNet的Com+分布式事务处理的配置与调试

    DotNet的Com+分布式事务处理的配置与调试 分别讲述sql2000及sql2005中关于分布式事务处理所需的配置。 附有代码。 该文档有47页,内容丰富

    微服务架构的分布式事务解决方案

    这事关于分布式事务的处理视频教程,内容很详细,网上绝大多数都要解压码,这个视频教程是本人在某宝商花重金购买的哦,绝对不加密,而且里面还包含相关的课件。

    dtx.zip:分布式事务英文资料小集

    收集的一些关于在现代开发运行环境(微服务等)下,解决分布式事务的论文。包括古老的saga论文,Atomikos公司Guy同学的一些想法及其它。

    服务架构的分布式事务解决方案

    为了解决大家在实施分布式服务化架构过程中关于事问题的困扰,教将基 为了解决大家在实施分布式服务化架构过程中关于事问题的困扰,教将基 为了解决大家在实施分布式服务化架构过程中关于事问题的困扰,教将基 为了...

    一篇文章彻底搞懂“分布式事务”

    这个时候为了完成一个简单的业务功能,比如:购买商品后扣款,有可能需要横跨多个服务,涉及用户订单、商品库存、支付等多个数据库,而这些操作又需要在同一个事务中完,这就涉及到到了分布式事务。本质上来说,...

    大规模SOA系统中的分布事务处事_程立

    2008年2月支付宝程立在中国软件大会上,作的关于分布式事务的经典PPT,分布式开发者必读只经典。

    基于SpringBoot2+RabbitMQ实现分布式事务解决方案.zip

    基于SpringBoot2+RabbitMQ实现分布式事务解决方案.zip 关于RabbitMQ实现分布式事务解决方案 框架整合:SpringBoot2+MyBatis+RabbitMQ 需要两个MySQL节点以及至少一个可用的RabbitMQ节点

    分布式事务:不过是在一致性、吞吐量和复杂度之间,做一个选择

    这是一个开撕的话题,我经历过太多的关于分布式事务的需求:“有没有简单的方案,像使用数据库事务那样,解决分布式数据一致性的问题”。特别是微服务架构流行的今天,一次交易需要跨越多个“服务”、多个数据库来...

    Spring+Mybatis+Atomikos实现JAVA初始化并控制多个数据源+分布式事务

    Spring+Mybatis+Atomikos实现JAVA初始化并控制多个数据源+分布式事务的一个DEMO,内涵源代码,以及一篇关于该内容的博客

    JAVA大礼包,微服务,分布式事务,hadoop,Docker

    本人把在CSDN下载的很多关于JAVA技术的连接集合在了一起,主要要JAVA基础,JAVA高级,微服务,分布式事务,大数据。里面的各种资源需要你去筛选,愿你淘到满意的内容。如有版权问题请联系数据源或者是CSDN,也请联系...

    基于SpringBoot的seata1.4.2项目,Nacos分布式事务实现

    搭建项目时遇到了一些问题,在网上找到了不少关于seata的配置文章,有的博主用老版本的思路在发文章,导致新手做了很多无用功,踩了不少坑总算是实现了seata的分布式事务,在此将这个试错demo项目分享出来,供各位...

Global site tag (gtag.js) - Google Analytics