#0 系列目錄#java
#1 Atomikos使用非XA數據庫驅動實現分佈式事務# 項目地址見:Atomikos使用非XA數據庫驅動實現分佈式事務mysql
##1.1 業務邏輯的操做## UserDao和LogDao,操做分別以下:git
@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綜合上述兩個業務操做,使它們處於同一個事務中:spring
@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(); } }
##1.2 配置## 上述業務代碼咱們看不到分佈式事務的存在,這種正是咱們想要的效果,分佈式事務對業務透明。究竟是如何來實現呢? ###1.2.1 dataSource和JdbcTemplate配置###sql
<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&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&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
。數據庫
###1.2.2 事務配置### 咱們知道分佈式事務中須要一個事務管理器即接口javax.transaction.TransactionManager、面向開發人員的javax.transaction.UserTransaction。對於Atomikos來講分別對應以下:分佈式
咱們若是想使用分佈式事務的同時,又想使用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加入進當前線程綁定的事務呢?這時候就須要能夠經過靜態方法隨時獲取當前線程綁定的事務
。atom
###1.2.3 jar包依賴### 這裏只使用了Atomikos,不像jotm還使用了xapool。url
<!-- atomikos --> <dependency> <groupId>com.atomikos</groupId> <artifactId>transactions-jdbc</artifactId> <version>4.0.0M4</version> </dependency>
#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.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&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&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配置,其餘內容都同樣
。
###2.2.2 事務配置### 咱們知道分佈式事務中須要一個事務管理器即接口javax.transaction.TransactionManager、面向開發人員的javax.transaction.UserTransaction。對於Atomikos來講分別對應以下:
咱們若是想使用分佈式事務的同時,又想使用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"/>
###2.2.3 jar包依賴### 這裏只使用了Atomikos,不像jotm還使用了xapool。
<!-- atomikos --> <dependency> <groupId>com.atomikos</groupId> <artifactId>transactions-jdbc</artifactId> <version>4.0.0M4</version> </dependency>