开发传统应用遇到的最大问题就是多数据源的事务一致性问题, 下面介绍一种常用的分布式事务处理方式的使用
开发环境:Eclipse+Java1.7 + Tomcat7, 另外使用到的开源框架 Spring3.X
提到分布式事务大家首先想到的肯定是jta,我们用到的就是基于jta的一种实现atomikos,下面就介绍一下他的使用
1、依赖的jar
Maven依赖代码
<!--atomikos 分布式事务依赖 -->
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jta</artifactId>
<version>${atomikos.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jdbc</artifactId>
<version>${atomikos.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>${jta.version}</version>
<optional>true</optional>
</dependency>
<!--数据源的连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
2、 配置数据源
数据源连接池,必须是支持XA标准的连接池,什么是XA标准呢?
XA协议由Tuxedo首先提出的,并交给X/Open组织,作为资源管理器(数据库)与事务管理器的接口标准。目前,Oracle、Informix、DB2和Sybase等各大数据库厂家都提供对XA的支持。XA协议采用两阶段提交方式来管理分布式事务。XA接口提供资源管理器与事务管理器之间进行通信的标准接口。XA协议包括两套函数,以xa_开头的及以ax_开头的。
以下的函数使事务管理器可以对资源管理器进行的操作:
1)xa_open,xa_close:建立和关闭与资源管理器的连接。
2)xa_start,xa_end:开始和结束一个本地事务。
3)xa_prepare,xa_commit,xa_rollback:预提交、提交和回滚一个本地事务。
4)xa_recover:回滚一个已进行预提交的事务。
5)ax_开头的函数使资源管理器可以动态地在事务管理器中进行注册,并可以对XID(TRANSACTION IDS)进行操作。
6)ax_reg,ax_unreg;允许一个资源管理器在一个TMS(TRANSACTION MANAGER SERVER)中动态注册或撤消注册。
Java代码
<!--dataSource-->
<bean init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property value="${jdbc.url}" />
<property value="${jdbc.username}" />
<property value="${jdbc.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property value="${jdbc.initialSize}" />
<property value="${jdbc.minIdle}" />
<property value="${jdbc.maxIdle}" />
<property value="${jdbc.maxActive}" />
<!-- 配置获取连接等待超时的时间 -->
<property value="${jdbc.maxWait}"/>
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property value="${jdbc.timeBetweenEvictionRunsMillis}" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property value="${jdbc.minEvictableIdleTimeMillis}" />
<property value="${jdbc.validationQuery}" />
<property value="${jdbc.testWhileIdle}" />
<property value="${jdbc.testOnBorrow}" />
<property value="${jdbc.testOnReturn}" />
<property value="${jdbc.filters}" />
</bean>
<bean init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property value="${jdbc1.url}" />
<property value="${jdbc1.username}" />
<property value="${jdbc1.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property value="${jdbc.initialSize}" />
<property value="${jdbc.minIdle}" />
<property value="${jdbc.maxIdle}" />
<property value="${jdbc.maxActive}" />
<!-- 配置获取连接等待超时的时间 -->
<property value="${jdbc.maxWait}"/>
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property value="${jdbc.timeBetweenEvictionRunsMillis}" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property value="${jdbc.minEvictableIdleTimeMillis}" />
<property value="${jdbc.validationQuery}" />
<property value="${jdbc.testWhileIdle}" />
<property value="${jdbc.testOnBorrow}" />
<property value="${jdbc.testOnReturn}" />
<property value="${jdbc.filters}" />
</bean>
3、强数据源指定到AtomikosDataSourceBean中,再有该类的对象向DAO层提供数据源服务
配置如下
datasource1