http://log-cd.iteye.com/blog/807607

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

  1. public interface GenericDao {
  2. public int save(String ds, String sql, Object[] obj) throws Exception;
  3. public int findRowCount(String ds, String sql);
  4. }
  1. public class GenericDaoImpl implements GenericDao{
  2. private  JdbcTemplate jdbcTemplateA;
  3. private  JdbcTemplate jdbcTemplateB;
  4. public void setJdbcTemplateA(JdbcTemplate jdbcTemplate) {
  5. this.jdbcTemplateA = jdbcTemplate;
  6. }
  7. public void setJdbcTemplateB(JdbcTemplate jdbcTemplate) {
  8. this.jdbcTemplateB = jdbcTemplate;
  9. }
  10. public int save(String ds, String sql, Object[] obj) throws Exception{
  11. if(null == ds || "".equals(ds)) return -1;
  12. try{
  13. if(ds.equals("A")){
  14. return this.jdbcTemplateA.update(sql, obj);
  15. }else{
  16. return this.jdbcTemplateB.update(sql, obj);
  17. }
  18. }catch(Exception e){
  19. e.printStackTrace();
  20. throw new Exception("执行" + ds + "数据库时失败!");
  21. }
  22. }
  23. public int findRowCount(String ds, String sql) {
  24. if(null == ds || "".equals(ds)) return -1;
  25. if(ds.equals("A")){
  26. return this.jdbcTemplateA.queryForInt(sql);
  27. }else{
  28. return this.jdbcTemplateB.queryForInt(sql);
  29. }
  30. }
  31. }

(2)、Service及实现

  1. public interface UserService {
  2. public void saveUser() throws Exception;
  3. }
  1. public class UserServiceImpl implements UserService{
  2. private GenericDao genericDao;
  3. public void setGenericDao(GenericDao genericDao) {
  4. this.genericDao = genericDao;
  5. }
  6. public void saveUser() throws Exception {
  7. String userName = "user_" + Math.round(Math.random()*10000);
  8. System.out.println(userName);
  9. StringBuilder sql = new StringBuilder();
  10. sql.append(" insert into t_user(username, gender) values(?,?); ");
  11. Object[] objs = new Object[]{userName,"1"};
  12. genericDao.save("A", sql.toString(), objs);
  13. sql.delete(0, sql.length());
  14. sql.append(" insert into t_user(name, sex) values(?,?); ");
  15. objs = new Object[]{userName,"男的"};//值超出范围
  16. genericDao.save("B", sql.toString(), objs);
  17. }
  18. }

(3)、applicationContext-jotm.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:tx="http://www.springframework.org/schema/tx"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  8. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
  9. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
  10. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
  11. <description>springJTA</description>
  12. <!--指定Spring配置中用到的属性文件-->
  13. <bean id="propertyConfig"
  14. class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  15. <property name="locations">
  16. <list>
  17. <value>classpath:jdbc.properties</value>
  18. </list>
  19. </property>
  20. </bean>
  21. <!-- JOTM实例 -->
  22. <bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean">
  23. <property name="defaultTimeout" value="500000"/>
  24. </bean>
  25. <!-- JTA事务管理器 -->
  26. <bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
  27. <property name="userTransaction" ref="jotm" />
  28. </bean>
  29. <!-- 数据源A -->
  30. <bean id="dataSourceA" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
  31. <property name="dataSource">
  32. <bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
  33. <property name="transactionManager" ref="jotm"/>
  34. <property name="driverName" value="${jdbc.driver}"/>
  35. <property name="url" value="${jdbc.url}"/>
  36. </bean>
  37. </property>
  38. <property name="user" value="${jdbc.username}"/>
  39. <property name="password" value="${jdbc.password}"/>
  40. </bean>
  41. <!-- 数据源B -->
  42. <bean id="dataSourceB" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
  43. <property name="dataSource">
  44. <bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
  45. <property name="transactionManager" ref="jotm"/>
  46. <property name="driverName" value="${jdbc2.driver}"/>
  47. <property name="url" value="${jdbc2.url}"/>
  48. </bean>
  49. </property>
  50. <property name="user" value="${jdbc2.username}"/>
  51. <property name="password" value="${jdbc2.password}"/>
  52. </bean>
  53. <bean id = "jdbcTemplateA"
  54. class = "org.springframework.jdbc.core.JdbcTemplate">
  55. <property name = "dataSource" ref="dataSourceA"/>
  56. </bean>
  57. <bean id = "jdbcTemplateB"
  58. class = "org.springframework.jdbc.core.JdbcTemplate">
  59. <property name = "dataSource" ref="dataSourceB"/>
  60. </bean>
  61. <!-- 事务切面配置 -->
  62. <aop:config>
  63. <aop:pointcut id="pointCut"
  64. expression="execution(* com.logcd.service..*.*(..))"/><!-- 包及其子包下的所有方法 -->
  65. <aop:advisor pointcut-ref="pointCut" advice-ref="txAdvice"/>
  66. <aop:advisor pointcut="execution(* *..common.service..*.*(..))" advice-ref="txAdvice"/>
  67. </aop:config>
  68. <!-- 通知配置 -->
  69. <tx:advice id="txAdvice" transaction-manager="jtaTransactionManager">
  70. <tx:attributes>
  71. <tx:method name="delete*" rollback-for="Exception"/>
  72. <tx:method name="save*" rollback-for="Exception"/>
  73. <tx:method name="update*" rollback-for="Exception"/>
  74. <tx:method name="find*" read-only="true" rollback-for="Exception"/>
  75. </tx:attributes>
  76. </tx:advice>
  77. <bean id="genericDao"
  78. class="com.logcd.dao.impl.GenericDaoImpl" autowire="byName">
  79. </bean>
  80. <bean id="userService"
  81. class="com.logcd.service.impl.UserServiceImpl" autowire="byName">
  82. </bean>
  83. </beans>

(4)、测试

  1. public class TestUserService{
  2. private static UserService userService;
  3. @BeforeClass
  4. public static void init(){
  5. ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext-jotm.xml");
  6. userService = (UserService)app.getBean("userService");
  7. }
  8. @Test
  9. public void save(){
  10. System.out.println("begin...");
  11. try{
  12. userService.saveUser();
  13. }catch(Exception e){
  14. System.out.println(e.getMessage());
  15. }
  16. System.out.println("finish...");
  17. }
  18. }

二、关于使用atomikos实现 

(1)、数据源配置

  1. <bean id="dataSourceA" class="com.atomikos.jdbc.SimpleDataSourceBean" init-method="init" destroy-method="close">
  2. <property name="uniqueResourceName">
  3. <value>${datasource.uniqueResourceName}</value>
  4. </property>
  5. <property name="xaDataSourceClassName">
  6. <value>${database.driver_class}</value>
  7. </property>
  8. <property name="xaDataSourceProperties">
  9. <value>URL=${database.url};user=${database.username};password=${database.password}</value>
  10. </property>
  11. <property name="exclusiveConnectionMode">
  12. <value>${connection.exclusive.mode}</value>
  13. </property>
  14. <property name="connectionPoolSize">
  15. <value>${connection.pool.size}</value>
  16. </property>
  17. <property name="connectionTimeout">
  18. <value>${connection.timeout}</value>
  19. </property>
  20. <property name="validatingQuery">
  21. <value>SELECT 1</value>
  22. </property>
  23. </bean>

(2)、事务配置

  1. <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
  2. init-method="init" destroy-method="close">
  3. <property name="forceShutdown" value="true"/>
  4. </bean>
  5. <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
  6. <property name="transactionTimeout" value="${transaction.timeout}"/>
  7. </bean>
  8. <!-- JTA事务管理器 -->
  9. <bean id="springTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
  10. <property name="transactionManager" ref="atomikosTransactionManager"/>
  11. <property name="userTransaction" ref="atomikosUserTransaction"/>
  12. </bean>
  13. <!-- 事务切面配置 -->
  14. <aop:config>
  15. <aop:pointcut id="serviceOperation"  expression="execution(* *..service*..*(..))"/>
  16. <aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice"/>
  17. </aop:config>
  18. <!-- 通知配置 -->
  19. <tx:advice id="txAdvice" transaction-manager="springTransactionManager">
  20. <tx:attributes>
  21. <tx:method name="*" rollback-for="Exception"/>
  22. </tx:attributes>
  23. </tx:advice>

最后,补充一下POM配置:

		<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>javax.resource</groupId>
<artifactId>connector-api</artifactId>
<version>1.6-alpha-1</version>
</dependency>
<dependency>
<groupId>com.experlog</groupId>
<artifactId>xapool</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>org.ow2.jotm</groupId>
<artifactId>jotm-core</artifactId>
<version>2.2.2</version>
</dependency>

Spring分布式事务实现(适用于spring-tx 2.5)的更多相关文章

  1. spring分布式事务学习笔记

    最近项目中使用了分布式事务,本文及接下来两篇文章总结一下在项目中学到的知识. 分布式事务对性能有一定的影响,所以不是最佳的解决方案,能通过设计避免最好尽量避免. 分布式事务(Distributed t ...

  2. Spring分布式事务实现概览

    分布式事务,一直是实现分布式系统过程中最大的挑战.在只有单个数据源的单服务系统当中,只要这个数据源支持事务,例如大部分关系型数据库,和一些MQ服务,如activeMQ等,我们就可以很容易的实现事务. ...

  3. Spring分布式事务

    [如何实现XA式.非XA式Spring分布式事务] [http://www.importnew.com/15812.html] 在JavaWorld大会上,来自SpringSource的David S ...

  4. 分布式事务操作之Spring+JTA

    什么是分布式事务?在网上找了一段比较容易理解的"定义". 分布式事务是指事务的参与者.支持事务的服务器.资源管理器以及事务管理器分别位于分布系统的不同节点之上,在两个或多个网络计算 ...

  5. Spring分布式事务实现

    分布式事务是指操作多个数据库之间的事务,spring的org.springframework.transaction.jta.JtaTransactionManager,提供了分布式事务支持.如果使用 ...

  6. spring分布式事务学习笔记(1)

    此文已由作者夏昀授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 分布式事务对性能有一定的影响,所以不是最佳的解决方案,能通过设计避免最好尽量避免. 分布式事务(Distrib ...

  7. atomikos实现多数据源支持分布式事务管理(spring、tomcat、JTA)

    原文链接:http://iteye.blog.163.com/blog/static/1863080962012102945116222/   Atomikos TransactionsEssenti ...

  8. Spring 分布式事务详解

    在学习分布式事务的过程中会遇到以下关键名词: 相关名词: XA :XA规范的目的是允许多个资源(如数据库,应用服务器,消息队列,等等)在同一事务中访问,这样可以使ACID属性跨越应用程序而保持有效.X ...

  9. 如何实现XA式、非XA式Spring分布式事务

    Spring应用的几种事务处理机制 Java Transaction API和XA协议是Spring常用的分布式事务机制,不过你可以选择选择其他的实现方式.理想的实现取决于你的应用程序使用何种资源,你 ...

随机推荐

  1. Vmware Ubuntu 虚拟机下Android开发环境搭建

    概况: 1.安装jdk: 2.安装adt-bundle: 1.安装jdk 先下载linux下的jdk,我下的是 jdk-7u13-linux-i586 :然后解压,为方便,建个文件夹--/home/x ...

  2. FTP被动模式连接及超时问题解决

    问题: 1.FTPClient.listFiles()或者FTPClient.retrieveFile()方法时,就停止在那里,什么反应都没有,出现假死状态. 2.连接FTP服务器,长时间进行数据操作 ...

  3. javascript之函数篇

    1.我们都知道定义函数有两种方式:函数声明和函数表达式(其实还有Function构造函数方式,不推荐使用) 如: 声明方式:function sum(num1,num2){returm num1+nu ...

  4. 如何检查机器是否因为装了Windows更新而需要重新启动

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:如何检查机器是否因为装了Windows更新而需要重新启动.

  5. JS基础DOM篇之一:何为DOM?

    近日在园子看了一篇文章,一位前端负责人问应聘者何为DOM事件流的三个阶段,我当时一看也是懵圈,于是强迫症复发,遂想要搞清楚它.谁知在查资料的过程中发现有好多关于DOM的概念也是模糊不清,便决定继续延伸 ...

  6. 连载:面向对象葵花宝典:思想、技巧与实践(32) - LSP原则

    LSP是唯一一个以人名命名的设计原则,并且作者还是一个"女博士"  ======================================================== ...

  7. MmSystem播放Wav格式声音

    //MmSystem播放Wav格式声音 //MmSystem 支持 *.wav声音格式 snd ->SoundRecorderuses MmSystem; //引用MmSystem//播放系统声 ...

  8. OpenCV 显示Mat矩阵异常 显示“程序停止工作” 解决办法

    笔者调试OpenCV 程序时,在使用标准输出显示Mat矩阵时,编译没有错误,但每次运行都弹出程序停止工作的对话框.google之,得到解决方案. 程序如下: #include <iostream ...

  9. 50个Android开发技巧(02 延迟载入和避免反复渲染视图)

    当你在Application中创建复杂的布局时.页面的渲染过程也变得更加缓慢. 此时,我们须要利用 <include />标签(避免反复渲染)和 ViewStub类(延迟载入)来优化我们的 ...

  10. eclipse @override错误

    @Override是JDK5 就已经有了,但有个小小的Bug,就是不支持对接口的实现,认为这不是Override而JDK6 修正了这个Bug,无论是对父类的方法覆盖还是对接口的实现都可以加上@Over ...