分布式事务系列(4.1)Atomikos的分布式案例

1 系列目录

2 Atomikos使用非XA数据库驱动实现分布式事务

项目地址见:Atomikos使用非XA数据库驱动实现分布式事务

2.1 业务逻辑的操作

UserDao和LogDao,操作分别如下:

@Repository
public class UserDao {

    @Resource(name="jdbcTemplateA")
    private JdbcTemplate jdbcTemplate;

    public void save(User user){
        jdbcTemplate.update("insert into user(name,age) values(?,?)",user.getName(),user.getAge());
    }
}

@Repository
public class LogDao {

    @Resource(name="jdbcTemplateB")
    private JdbcTemplate jdbcTemplate;

    public void save(User user){
        jdbcTemplate.update("insert into log(name,age) values(?,?)",user.getName(),user.getAge());
    }
}

即上述两个JdbcTemplate使用不同的数据库。

UserService综合上述两个业务操作,使它们处于同一个事务中:

@Service
public class UserService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private LogDao logDao;

    @Transactional
    public void save(User user){
        userDao.save(user);
        logDao.save(user);
        throw new RuntimeException();
    }
}

2.2 配置

上述业务代码我们看不到分布式事务的存在,这种正是我们想要的效果,分布式事务对业务透明。到底是如何来实现呢?

2.2.1 dataSource和JdbcTemplate配置

<bean id="dataSourceA" class="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean" init-method="init"  destroy-method="close">
    <property name="uniqueResourceName" value="XA1DBMS" />  

       <property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf-8" />
       <property name="user" value="root" />
       <property name="password" value="xxxx" />
       <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 

    <property name="poolSize" value="3" />
    <property name="minPoolSize" value="3" />
    <property name="maxPoolSize" value="5" />
</bean>

<bean id="dataSourceB" class="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean" init-method="init" destroy-method="close">
    <property name="uniqueResourceName" value="XA2DBMS" />  

    <property name="url" value="jdbc:mysql://localhost:3306/test2?useUnicode=true&amp;characterEncoding=utf-8" />
       <property name="user" value="root" />
       <property name="password" value="xxxx" />
       <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 

    <property name="poolSize" value="3" />
    <property name="minPoolSize" value="3" />
    <property name="maxPoolSize" value="5" />
</bean>

<bean id="jdbcTemplateA" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSourceA" />
</bean>  

<bean id="jdbcTemplateB" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSourceB" />
</bean>

自行配置2个数据库地址

我们平常使用的dataSource,大部分是c3p0、dbcp等,这里就不能使用它们了,需要换成可以模拟XA协议的dataSource,这里即AtomikosNonXADataSourceBean。

2.2.2 事务配置

我们知道分布式事务中需要一个事务管理器即接口javax.transaction.TransactionManager、面向开发人员的javax.transaction.UserTransaction。对于Atomikos来说分别对应如下:

  • com.atomikos.icatch.jta.UserTransactionImp
  • com.atomikos.icatch.jta.UserTransactionManager

我们如果想使用分布式事务的同时,又想使用Spring带给我们的@Transactional便利,就需要配置一个JtaTransactionManager,而该JtaTransactionManager是需要一个userTransaction实例的

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

<bean id="springTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="userTransaction" ref="userTransaction" />
</bean>

<tx:annotation-driven transaction-manager="springTransactionManager"/>

可以对比下jotm的案例配置jotm的分布式事务配置。可以看到jotm中使用的xapool中的StandardXADataSource是需要一个transactionManager的,而Atomikos使用的AtomikosNonXADataSourceBean则不需要。我们知道,StandardXADataSource中有了transactionManager就可以获取当前线程的事务,同时把XAResource加入进当前事务中去,而AtomikosNonXADataSourceBean却没有,它是怎么把XAResource加入进当前线程绑定的事务呢?这时候就需要可以通过静态方法随时获取当前线程绑定的事务。

2.2.3 jar包依赖

这里只使用了Atomikos,不像jotm还使用了xapool。

<!-- atomikos -->
<dependency>
    <groupId>com.atomikos</groupId>
    <artifactId>transactions-jdbc</artifactId>
    <version>4.0.0M4</version>
</dependency>

3 Atomikos使用XA数据库驱动实现分布式事务

项目地址见:Atomikos使用非XA数据库驱动实现分布式事务

3.1 业务逻辑的操作

UserDao和LogDao,操作分别如下:

@Repository
public class UserDao {

    @Resource(name="jdbcTemplateA")
    private JdbcTemplate jdbcTemplate;

    public void save(User user){
        jdbcTemplate.update("insert into user(name,age) values(?,?)",user.getName(),user.getAge());
    }
}

@Repository
public class LogDao {

    @Resource(name="jdbcTemplateB")
    private JdbcTemplate jdbcTemplate;

    public void save(User user){
        jdbcTemplate.update("insert into log(name,age) values(?,?)",user.getName(),user.getAge());
    }
}

即上述两个JdbcTemplate使用不同的数据库。

UserService综合上述两个业务操作,使它们处于同一个事务中:

@Service
public class UserService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private LogDao logDao;

    @Transactional
    public void save(User user){
        userDao.save(user);
        logDao.save(user);
        throw new RuntimeException();
    }
}

3.2 配置

上述业务代码我们看不到分布式事务的存在,这种正是我们想要的效果,分布式事务对业务透明。到底是如何来实现呢?

3.2.1 dataSource和JdbcTemplate配置

<bean id="dataSourceA" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
    <property name="uniqueResourceName" value="XA1DBMS" />
    <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
    <property name="xaProperties">
        <props>
            <prop key="URL">jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf-8</prop>
            <prop key="user">root</prop>
            <prop key="password">ligang</prop>
        </props>
    </property>
    <property name="poolSize" value="3" />
    <property name="minPoolSize" value="3" />
    <property name="maxPoolSize" value="5" />
</bean>

<bean id="dataSourceB" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
    <property name="uniqueResourceName" value="XA2DBMS" />
    <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
    <property name="xaProperties">
        <props>
            <prop key="URL">jdbc:mysql://localhost:3306/test2?useUnicode=true&amp;characterEncoding=utf-8</prop>
            <prop key="user">root</prop>
            <prop key="password">ligang</prop>
        </props>
    </property>
    <property name="poolSize" value="3" />
    <property name="minPoolSize" value="3" />
    <property name="maxPoolSize" value="5" />
</bean>

自行配置上述2个数据库地址

我们平常使用的dataSource,大部分是c3p0、dbcp等,这里就不能使用它们了,需要换成可以Atomikos自己的dataSource,这里即AtomikosDataSourceBean。它需要使用支持XA的jdbc驱动。具体就是需要一个xaDataSourceClassName,我们这里使用的是mysql支持xa的的MysqlXADataSource,它实现了javax.sql.XADataSource接口,即可以产生XAConnection连接。

Atomikos使用非XA数据库驱动实现分布式事务 与 Atomikos使用XA数据库驱动实现分布式事务唯一配置上的不同就是这里的dataSource配置,其他内容都一样。

3.2.2 事务配置

我们知道分布式事务中需要一个事务管理器即接口javax.transaction.TransactionManager、面向开发人员的javax.transaction.UserTransaction。对于Atomikos来说分别对应如下:

  • com.atomikos.icatch.jta.UserTransactionImp
  • com.atomikos.icatch.jta.UserTransactionManager

我们如果想使用分布式事务的同时,又想使用Spring带给我们的@Transactional便利,就需要配置一个JtaTransactionManager,而该JtaTransactionManager是需要一个userTransaction实例的

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

<bean id="springTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="userTransaction" ref="atomikosUserTransaction" />
</bean>

<tx:annotation-driven transaction-manager="springTransactionManager"/>

3.2.3 jar包依赖

这里只使用了Atomikos,不像jotm还使用了xapool。

<!-- atomikos -->
<dependency>
    <groupId>com.atomikos</groupId>
    <artifactId>transactions-jdbc</artifactId>
    <version>4.0.0M4</version>
</dependency>

4 结束语

本文介绍了Atomikos使用XA数据库驱动和非XA数据库驱动两种方式来实现分布式事务的案例,下一篇文章就来详细说明下其中的原理。

  • 在Atomikos中,2PC的中的协调者是谁?参与者又是谁?
  • 在XA数据库驱动和非XA数据库驱动两种情况下,事务是怎么开启的?当执行业务操作的时候,参与者又是怎么加入事务中的呢?2PC的过程又是怎么进行的?事务是怎么回滚的?事务是怎么提交的呢?
时间: 2024-09-11 12:42:34

分布式事务系列(4.1)Atomikos的分布式案例的相关文章

分布式事务系列(2.1)分布式事务的概念

1 系列目录 分布式事务系列(开篇)提出疑问和研究过程 分布式事务系列(1.1)Spring事务管理器PlatformTransactionManager源码分析 分布式事务系列(1.2)Spring事务体系 分布式事务系列(2.1)分布式事务模型与接口定义 分布式事务系列(3.1)jotm的分布式案例 分布式事务系列(3.2)jotm分布式事务源码分析 分布式事务系列(4.1)Atomikos的分布式案例 2 X/Open DTP DTP全称是Distributed Transaction P

分布式事务系列(3.2)jotm分布式事务源码分析

1 系列目录 分布式事务系列(开篇)提出疑问和研究过程 分布式事务系列(1.1)Spring事务管理器PlatformTransactionManager源码分析 分布式事务系列(1.2)Spring事务体系 分布式事务系列(2.1)分布式事务模型与接口定义 分布式事务系列(3.1)jotm的分布式案例 分布式事务系列(3.2)jotm分布式事务源码分析 分布式事务系列(4.1)Atomikos的分布式案例 2 了解xapool 我们在前一篇文章中了解到jotm配合xapool共同完成了分布式事

分布式事务系列(1.2)Spring的事务体系

1 系列目录 分布式事务系列(开篇)提出疑问和研究过程 分布式事务系列(1.1)Spring事务管理器PlatformTransactionManager源码分析 分布式事务系列(1.2)Spring事务体系 分布式事务系列(2.1)分布式事务模型与接口定义 分布式事务系列(3.1)jotm的分布式案例 分布式事务系列(3.2)jotm分布式事务源码分析 分布式事务系列(4.1)Atomikos的分布式案例 2 三种事务模型 三种事务模型如下: 本地事务模型 编程式事务模型 声明式事务模型 先来

分布式事务系列(开篇)提出疑问和研究过程

1 前言 系列目录 分布式事务系列(开篇)提出疑问和研究过程 分布式事务系列(1.1)Spring事务管理器PlatformTransactionManager源码分析 分布式事务系列(1.2)Spring事务体系 分布式事务系列(2.1)分布式事务模型与接口定义 分布式事务系列(3.1)jotm的分布式案例 分布式事务系列(3.2)jotm分布式事务源码分析 分布式事务系列(4.1)Atomikos的分布式案例 对于我们这种初学者,可能会使用spring带给我们的@Transactional,

分布式事务系列(1.1)Spring事务管理器PlatformTransactionManager

1 系列目录 分布式事务系列(开篇)提出疑问和研究过程 分布式事务系列(1.1)Spring事务管理器PlatformTransactionManager源码分析 分布式事务系列(1.2)Spring事务体系 分布式事务系列(2.1)分布式事务模型与接口定义 分布式事务系列(3.1)jotm的分布式案例 分布式事务系列(3.2)jotm分布式事务源码分析 分布式事务系列(4.1)Atomikos的分布式案例 2 jdbc事务 2.1 例子 public void save(User user)

分布式事务系列(3.1)jotm的分布式案例

1 系列目录 分布式事务系列(开篇)提出疑问和研究过程 分布式事务系列(1.1)Spring事务管理器PlatformTransactionManager源码分析 分布式事务系列(1.2)Spring事务体系 分布式事务系列(2.1)分布式事务模型与接口定义 分布式事务系列(3.1)jotm的分布式案例 分布式事务系列(3.2)jotm分布式事务源码分析 分布式事务系列(4.1)Atomikos的分布式案例 2 与Spring集成方式使用jotm 工程代码地址:与Spring集成方式使用jotm

Spring多数据源分布式事务管理/springmvc+spring+atomikos[jta]+druid+mybatis

项目进行读写分离及分库分表,在一个业务中,在一个事务中处理时候将切换多个数据源,需要保证同一事务多个数据源数据的一致性.此处使用atomikos来实现:最后附源码: 1:spring3.0之后不再支持jtom[jta]了,第三方开源软件atomikos(http://www.atomikos.com/)来实现.  2:org.springframework.transaction.jta.JotmFactoryBean类,spring-tx-2.5.6.jar中有此类,spring-tx-3.0

WCF分布式开发步步为赢(12):WCF事务机制(Transaction)和分布式事务编程

今天我们继续学习WCF分布式开发步步为赢系列的12节:WCF事务机制(Transaction)和分布式事务编程.众所周知,应用系统开发过程中,事务是一个重要的概念.它是保证数据与服务可靠性的重要机制.作为面向服务应用的开发平台,WCF也提供了对事物编程模型的支持..NET 2.0提供的System.Transactions类来开发事务应用程序.同样WCF也支持事务特性,WCF事务机制是什么,它与微软已有的技术如Microsoft 分布式事务协调器 (MSDTC)有何关系?与Enterpise S

关于分布式事务

一.普通事务与分布式事务 1.1 普通事务 普通事务就是一般所说的数据库事务,大家对数据库事务应该都很了解,这里再简单介绍下. 事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成.当事务被提交给了DBMS(数据库管理系统),则DBMS(数据库管理系统)需要确保该事务中的所有操作都成功完成且其结果被永久保存在数据库中,如果事务中有的操作没有成功完成,则事务中的所有操作都需要被回滚,回到事务执行前的状态;同时,该事务对数据库或者其他事务的执行无影响,所有的事务都好像在独立的