分布式事务是指操作多个数据库之间的事务,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及实现

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

public class GenericDaoImpl implements GenericDao{  private  JdbcTemplate jdbcTemplateA;  private  JdbcTemplate jdbcTemplateB;  public void setJdbcTemplateA(JdbcTemplate jdbcTemplate) {  this.jdbcTemplateA = jdbcTemplate;  }  public void setJdbcTemplateB(JdbcTemplate jdbcTemplate) {  this.jdbcTemplateB = jdbcTemplate;  }  public int save(String ds, String sql, Object[] obj) throws Exception{  if(null == ds || "".equals(ds)) return -1;  try{  if(ds.equals("A")){  return this.jdbcTemplateA.update(sql, obj);  }else{  return this.jdbcTemplateB.update(sql, obj);  }  }catch(Exception e){  e.printStackTrace();  throw new Exception("执行" + ds + "数据库时失败!");  }  }  public int findRowCount(String ds, String sql) {  if(null == ds || "".equals(ds)) return -1;  if(ds.equals("A")){  return this.jdbcTemplateA.queryForInt(sql);  }else{  return this.jdbcTemplateB.queryForInt(sql);  }  }  }

(2)、Service及实现

public interface UserService {  public void saveUser() throws Exception;  } 

public class UserServiceImpl implements UserService{  private GenericDao genericDao;  public void setGenericDao(GenericDao genericDao) {  this.genericDao = genericDao;  }  public void saveUser() throws Exception {  String userName = "user_" + Math.round(Math.random()*10000);  System.out.println(userName);  StringBuilder sql = new StringBuilder();  sql.append(" insert into t_user(username, gender) values(?,?); ");  Object[] objs = new Object[]{userName,"1"};  genericDao.save("A", sql.toString(), objs);  sql.delete(0, sql.length());  sql.append(" insert into t_user(name, sex) values(?,?); ");  objs = new Object[]{userName,"男的"};//值超出范围  genericDao.save("B", sql.toString(), objs);  }  } 

(3)、applicationContext-jotm.xml

<?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:context="http://www.springframework.org/schema/context"   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.5.xsd   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">  <description>springJTA</description>  <!--指定Spring配置中用到的属性文件-->   <bean id="propertyConfig"   class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">   <property name="locations">   <list>   <value>classpath:jdbc.properties</value>   </list>   </property>   </bean>   <!-- JOTM实例 -->  <bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean">  <property name="defaultTimeout" value="500000"/>  </bean>  <!-- JTA事务管理器 -->  <bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">     <property name="userTransaction" ref="jotm" />     </bean>  <!-- 数据源A -->   <bean id="dataSourceA" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">   <property name="dataSource">   <bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">   <property name="transactionManager" ref="jotm"/>   <property name="driverName" value="${jdbc.driver}"/>   <property name="url" value="${jdbc.url}"/>   </bean>   </property>   <property name="user" value="${jdbc.username}"/>   <property name="password" value="${jdbc.password}"/>   </bean>   <!-- 数据源B -->   <bean id="dataSourceB" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">   <property name="dataSource">   <bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">   <property name="transactionManager" ref="jotm"/>   <property name="driverName" value="${jdbc2.driver}"/>   <property name="url" value="${jdbc2.url}"/>   </bean>   </property>   <property name="user" value="${jdbc2.username}"/>   <property name="password" value="${jdbc2.password}"/>   </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>      <!-- 事务切面配置 -->   <aop:config>   <aop:pointcut id="pointCut"  expression="execution(* com.logcd.service..*.*(..))"/><!-- 包及其子包下的所有方法 -->  <aop:advisor pointcut-ref="pointCut" advice-ref="txAdvice"/>   <aop:advisor pointcut="execution(* *..common.service..*.*(..))" advice-ref="txAdvice"/>  </aop:config>   <!-- 通知配置 -->   <tx:advice id="txAdvice" transaction-manager="jtaTransactionManager">   <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="find*" read-only="true" rollback-for="Exception"/>   </tx:attributes>   </tx:advice>   <bean id="genericDao"   class="com.logcd.dao.impl.GenericDaoImpl" autowire="byName">  </bean>  <bean id="userService"   class="com.logcd.service.impl.UserServiceImpl" autowire="byName">  </bean>  </beans> 

(4)、测试

public class TestUserService{  private static UserService userService;  @BeforeClass  public static void init(){  ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext-jotm.xml");  userService = (UserService)app.getBean("userService");  }  @Test  public void save(){  System.out.println("begin...");  try{  userService.saveUser();  }catch(Exception e){  System.out.println(e.getMessage());  }  System.out.println("finish...");  }  }

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

<bean id="dataSourceA" class="com.atomikos.jdbc.SimpleDataSourceBean" init-method="init" destroy-method="close">  <property name="uniqueResourceName">  <value>${datasource.uniqueResourceName}</value>  </property>  <property name="xaDataSourceClassName">   <value>${database.driver_class}</value>   </property>   <property name="xaDataSourceProperties">  <value>URL=${database.url};user=${database.username};password=${database.password}</value>   </property>   <property name="exclusiveConnectionMode">   <value>${connection.exclusive.mode}</value>   </property>  <property name="connectionPoolSize">   <value>${connection.pool.size}</value>  </property>  <property name="connectionTimeout">  <value>${connection.timeout}</value>  </property>  <property name="validatingQuery">   <value>SELECT 1</value>   </property>
</bean>

(2)、事务配置

<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="${transaction.timeout}"/>
</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="*" rollback-for="Exception"/>   </tx:attributes>
</tx:advice>

DTP模型之二:(XA协议之二)jotm分布式事务实现相关推荐

  1. 分布式事务(二)LCN分布式事务框架

    1. 简介 LCN框架在2017年6月发布第一个版本,目前最新已经达到5.0版本. LCN早期设计时,1.0版本和2.0版本设计步骤如下: 锁定事务单元(Lock) 确认事务模块状态(Confirm) ...

  2. 分布式事务理论-二阶段提交(Two-phase Commit)

    1 2PC 两阶段提交协议为了保证分布在不同节点上的分布式事务的一致性,我们需要引入一个协调者来管理所有的节点,负责各个本地资源的提交和回滚,并确保这些节点正确提交操作结果,若提交失败则放弃事务. 2 ...

  3. MySQL分布式事务(XA事务)

    MySQL分布式事务(XA事务) 官网:https://dev.mysql.com/doc/refman/5.7/en/xa.html 1.什么是分布式事务 分布式事务就是指事务的参与者.支持事务的服 ...

  4. 分布式事务2PC、3PC模型

    工作中使用最多的是本地事务,但是在对单一项目拆分为 SOA.微服务之后,就会牵扯出分布式事务场景 文章以分布式事务为主线展开说明,并且针对 2PC.3PC 算法进行详细的讲解,最后通过一个 Demo ...

  5. 分布式事务:XA,2PC,3PC,TCC,SEATA(AT)

    一.分布式事务产生原因 1.原本的数据是单库单表存储,随着业务的不断扩大数据量不断增多,单库性能支撑不了数据的更新与访问.为了解决数据库上的瓶颈,将数据库进行水平拆分,原来一个库里的事务操作,现在变成 ...

  6. MySQL中基于XA实现的分布式事务

    文章目录 一.前言 二.XA基础 2.1 XA基础知识 2.1.1 DTP是什么? 2.1.2 DTP的结构:AP TM RM(重点001) 2.1.3 DTP的重要概念 2.2 XA事务:基于两阶段 ...

  7. 分布式事务实战---XA两阶段提交(2PC)方案详解

    XA,2PC,two-phase commit protocol,两阶段事务提交采⽤的是 X/OPEN 组织定义的DTP 模型所抽象的: AP 应用程序,Application Program,定义事 ...

  8. 《深入理解分布式事务》第七章 XA 强一致性分布式事务原理

    <深入理解分布式事务>第七章 XA 强一致性分布式事务原理 文章目录 <深入理解分布式事务>第七章 XA 强一致性分布式事务原理 一.X/Open DTP 模型与 XA 规范 ...

  9. 深入解析:MySQL对分布式事务 XA Transactions 的支持

    导读:MySQL对分布式事务(XA Transactions)进行了很好的支持,我们看看它是怎么做的,并实战验证其提供的分布式事务控制语句效果. MySQL从5.0.3开始,InnoDB存储引擎支持X ...

最新文章

  1. centos7加固手册
  2. Freemarker基于模板字符串生成静态化html文件
  3. Educational Codeforces Round 117 (Rated for Div. 2)
  4. jupyternotebook运行python_jupyter notebook参数化运行python方式
  5. 日语学习-多邻国-饮食
  6. 7-134 敲笨钟 (20 分)
  7. [日志]家居清洁十大秘笈
  8. Spring按类型自动装配注入数组、集合、Map
  9. 【ZOJ 4097 The 19th Zhejiang University Programming Contest H】Rescue the Princess【边双连通缩点+LCA】
  10. 【BZOJ 3531 Sdoi2014】旅行【动态开点线段树+树链剖分】
  11. 专利学习——常用必备知识
  12. 启动solidworks时显示VBE6EXT.OLB不能被加载
  13. python“~”符号的用法
  14. 微信小程序拼团功能之表结构
  15. 往事如烟 - 简朴的老白树
  16. 20145212 罗天晨 MSF基础应用
  17. 如何使用CubeMX创建STM32F105的程序
  18. JavaScript 堆内存溢出
  19. 合并b站m4s格式的音视频轨道
  20. 气象绘图软件Panoply使用教程 (不定时更新)

热门文章

  1. 【APP】squid 3.0反向代理配置
  2. 什么是高层主管支持系统?
  3. js之argument小解
  4. iOS主线程耗时检测方案
  5. 浅谈jsp的7个动作
  6. 为什么自动化对于IT工程师是必须的?
  7. iframe,window,滚动栏的一些问题
  8. pxe+kickstart 实现基于网络的无人值守安装操作系统
  9. php ×××号码效验码生成函数
  10. Android中蓝牙的基本使用