现在的位置: 首页 > 综合 > 正文

java分布式事务——spring+jta+atomikos

2018年05月07日 ⁄ 综合 ⁄ 共 6421字 ⁄ 字号 评论关闭

Atomikos分两个:一个是开源的TransactionEssentials,一个是商业的ExtremeTransactions。

       TransactionEssentials的主要特征:JTA/XA 事务管理 —— 提供事务管理和连接池不需要应用服务器支持分布式事务(例如tomcat) 。TransactionEssentials可以在任何Java EE应用服务器中运行,也就是不依赖于任何应用服务器开源。TransactionEssentials是遵守Apache版本2许可的开源软件专注于JDBC/JMS —— 支持所有XA资源。


        Atomikos数据源配置方法有三种分别有:SimpleDataSourceBean、AtomikosDataSourceBean、AtomikosNonXADataSourceBean可任选一种。但是,使用atomikos时不能使用不支持jta的连接池,如c3p0。同样,如果使用jotm,也必须使用StandardXAPoolDataSource数据源配置。

SimpleDataSourceBean表示基础数据库连接配置;

AtomikosDataSourceBean表示必须要用到XA数据库驱动类,可设置连接池(经过测试推荐此方法);

AtomikosNonXADataSourceBean表示必须要用到普通数据库驱动类,可设置连接池;


1、实验环境:

spring
mysql5.1.51(需要版本5.0+)
AtomikosTransactionsEssentials-3.7.0 (详细可参加它的官网:http://www.atomikos.com   )
说明:
1. 测试的数据库需要支持分布式事务,同时JDBC要支持XA连接驱动。本次测试用的mysql5.1是支持事务的,JDBC驱动版本:mysql-connector-java-5.1.7-bin.jar,包含对 XA连接的支持:com.mysql.jdbc.jdbc2.optional.MysqlXAConnection
2. 附件提供AtomikosTransactionsEssentials 3.7.0 lib包下载:AtomikosTransactionsEssentials-3.7.0-lib.zip官方下载地址:http://www.atomikos.com/Main/TransactionsEssentialsDownloadForm,需要先注册才能下载。


2、创建表:

CREATE DATABASE IF NOT EXISTS testdb_a        DEFAULT CHARACTER SET utf8;    

USE testdb_a;    

DROP TABLE IF EXISTS tab_a;    

CREATE TABLE tab_a (    
        id bigint(20) NOT NULL,    
        name varchar(60) DEFAULT NULL,    
        address varchar(120) DEFAULT NULL,    
        PRIMARY KEY (id)    
) ENGINE=InnoDB DEFAULT CHARSET=utf8;    


CREATE DATABASE IF NOT EXISTS testdb_b        DEFAULT CHARACTER SET utf8;    

USE testdb_b;    

DROP TABLE IF EXISTS tab_b;    

CREATE TABLE tab_b (    
        id bigint(20) NOT NULL,    
        name varchar(60) DEFAULT NULL,    
        address varchar(120) DEFAULT NULL,    
        PRIMARY KEY (id)    
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3、配置文件:

<?xml version="1.0" encoding="UTF-8"?> 
<!-- 局部单元测试使用,不正式发布,不要删除 --> 
<beans xmlns="http://www.springframework.org/schema/beans" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xmlns:jee="http://www.springframework.org/schema/jee" 
             xmlns:aop="http://www.springframework.org/schema/aop" 
             xmlns:tx="http://www.springframework.org/schema/tx" 
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
                     http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd 
                     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd 
                     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> 

        <!--指定Spring配置中用到的属性文件--> 
        <bean id="propertyConfig" 
                    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
                <property name="locations"> 
                        <list> 
                                <value>classpath:jdbc.properties</value> 
                        </list> 
                </property> 
        </bean> 
        <!-- 数据源A --> 
        <bean id="dataSourceA" class="com.atomikos.jdbc.SimpleDataSourceBean" init-method="init" destroy-method="close"> 
                <property name="uniqueResourceName"> 
                        <value>mysql/db_a</value> 
                </property> 
                <property name="xaDataSourceClassName"> 
                        <value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value> 
                </property> 
                <property name="xaDataSourceProperties"> 
                        <value>URL=${jdbc.url};user=${jdbc.username};password=${jdbc.password}</value> 
                </property> 
                <property name="exclusiveConnectionMode"> 
                        <value>true</value> 
                </property> 
                <property name="connectionPoolSize"> 
                        <value>3</value> 
                </property> 
                <property name="validatingQuery"> 
                        <value>SELECT 1</value> 
                </property> 
        </bean> 
        <!-- 数据源B --> 
        <bean id="dataSourceB" class="com.atomikos.jdbc.SimpleDataSourceBean" init-method="init" destroy-method="close"> 
                <property name="uniqueResourceName"> 
                        <value>mysql/db_b</value> 
                </property> 
                <property name="xaDataSourceClassName"> 
                        <value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value> 
                </property> 
                <property name="xaDataSourceProperties"> 
                        <value>URL=${jdbc2.url};user=${jdbc2.username};password=${jdbc2.password}</value> 
                </property> 
                <property name="exclusiveConnectionMode"> 
                        <value>true</value> 
                </property> 
                <property name="connectionPoolSize"> 
                        <value>3</value> 
                </property> 
                <property name="validatingQuery"> 
                        <value>SELECT 1</value> 
                </property> 
        </bean> 

        <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" 
                    init-method="init" destroy-method="close"> 
                <property name="forceShutdown" value="true"/> 
        </bean> 

        <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"> 
                <property name="transactionTimeout" value="300"/> 
        </bean> 
        <!-- JTA事务管理器 --> 
        <bean id="springTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> 
                <property name="transactionManager" ref="atomikosTransactionManager"/> 
                <property name="userTransaction" ref="atomikosUserTransaction"/> 
        </bean> 


        <!-- 事务切面配置 --> 
        <aop:config> 
                <aop:pointcut id="serviceOperation" 
                                            expression="execution(* *..service*..*(..))"/> 
                <aop:advisor pointcut-ref="serviceOperation" 
                                         advice-ref="txAdvice"/> 
        </aop:config> 
        <!-- 通知配置 --> 
        <tx:advice id="txAdvice" transaction-manager="springTransactionManager"> 
                <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> 

        <!--根据dataSourceA和sql-map-config_A.xml创建一个SqlMapClientA--> 
        <bean id="sqlMapClientA" 
                    class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> 
                <property name="dataSource"> 
                        <ref local="dataSourceA"/> 
                </property> 
                <property name="configLocation"> 
                        <value>classpath:/sql-map-config_A.xml</value> 
                </property> 
        </bean> 
        <!--根据dataSourceB和sql-map-config_B.xml创建一个SqlMapClientB--> 
        <bean id="sqlMapClientB" 
                    class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> 
                <property name="dataSource"> 
                        <ref local="dataSourceB"/> 
                </property> 
                <property name="configLocation"> 
                        <value>classpath:/sql-map-config_B.xml</value> 
                </property> 
        </bean> 
        <!--根据sqlMapClientA创建一个SqlMapClientTemplate的模版类实例sqlMapClientTemplateA--> 
        <bean id="sqlMapClientTemplateA" 
                    class="org.springframework.orm.ibatis.SqlMapClientTemplate"> 
                <property name="sqlMapClient" ref="sqlMapClientA"/> 
        </bean> 
        <!--根据sqlMapClientB创建一个SqlMapClientTemplate的模版类实例sqlMapClientTemplateB--> 
        <bean id="sqlMapClientTemplateB" 
                    class="org.springframework.orm.ibatis.SqlMapClientTemplate"> 
                <property name="sqlMapClient" ref="sqlMapClientB"/> 
        </bean> 

        <!-- 配置DAO,并注入所使用的sqlMapClientTemplate实例 --> 
        <bean id="tabADAO" class="com.lavasoft.stu.atomikos.dao.impl.TabADAOImpl"> 
                <property name="sqlMapClientTemplate" ref="sqlMapClientTemplateA"/> 
        </bean> 
        <bean id="tabBDAO" class="com.lavasoft.stu.atomikos.dao.impl.TabBDAOImpl"> 
                <property name="sqlMapClientTemplate" ref="sqlMapClientTemplateB"/> 
        </bean> 

        <!-- Service配置,注入DAO --> 
        <bean id="stuJotmService" class="com.lavasoft.stu.atomikos.service.StuJotmServiceImpl"> 
                <property name="tabADAO" ref="tabADAO"/> 
                <property name="tabBDAO" ref="tabBDAO"/> 
        </bean> 
</beans>

抱歉!评论已关闭.