javaweb分布式事务

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

Java代码  

  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. }

Java代码  

  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及实现

Java代码  

  1. public interface UserService {
  2. public void saveUser() throws Exception;
  3. }

Java代码  

  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

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)、测试

Java代码  

  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)、数据源配置

Xml代码  

  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)、事务配置

Xml代码  

  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>
    • lib.rar (5.2 MB)
    • 描述: JOTM使用包
    • 转自:http://log-cd.iteye.com/blog/807607
时间: 2024-10-12 17:12:17

javaweb分布式事务的相关文章

XA分布式事务

XA分布式事务 XA XA协议由Tuxedo首先提出的,并交给X/Open组织,作为资源管理器(数据库)与事务管理器的接口标准.目前,Oracle.Informix.DB2和Sybase等各大数据库厂家都提供对XA的支持.XA协议采用两阶段提交方式来管理分布式事务.XA接口提供资源管理器与事务管理器之间进行通信的标准接口.XA协议包括两套函数,以xa_开头的及以ax_开头的 简介编辑 取决于上下文, XA 有多种意思. 我们常见的数据库连接交易中的 XA 是指由 X/Open 组织提出的分布式交

浅谈分布式事务

前言应用场景 事务必须满足传统事务的特性,即原子性,一致性,分离性和持久性.但是分布式事务处理过程中, 某些场地比如在电商系统中,当有用户下单后,除了在订单表插入一条记录外,对应商品表的这个商品数量必须减1吧,怎么保证? 在搜索广告系统中,当用户点击某广告后,除了在点击事件表中增加一条记录外,还得去商家账户表中找到这个商家并扣除广告费吧,怎么保证? 一 本地事务以用户A转账用户B为例,假设有 用户A账户表:A(id,userId,amount) 用户B账户表:B(id,userId,amount

聊聊分布式事务

聊聊分布式事务 2017-04-15 数据库开发 (点击上方公众号,可快速关注) 作者:员海滨 nickid.cn/2017/04/分布式事务/ 如有好文章投稿,请点击 → 这里了解详情 分布式事务场景如何设计系统架构及解决数据一致性问题,个人理解最终方案把握以下原则就可以了,那就是:大事务=小事务(原子事务)+异步(消息通知),解决分布式事务的最好办法其实就是不考虑分布式事务,将一个大的业务进行拆分,整个大的业务流程,转化成若干个小的业务流程,然后通过设计补偿流程从而考虑最终一致性. 什么是事

使用事件和消息队列实现分布式事务(转+补充)

虽然本文并非笔者原创,但是我们在非强依赖的事务中原理上也是采用这种方式处理的,不过因为没有仔细去总结,最近在整理和总结时看到了,故转载并做部分根据我们实际情况的完善和补充. 不同于单一架构应用(Monolith), 分布式环境下, 进行事务操作将变得困难, 因为分布式环境通常会有多个数据源, 只用本地数据库事务难以保证多个数据源数据的一致性. 这种情况下, 可以使用两阶段或者三阶段提交协议来完成分布式事务.但是使用这种方式一般来说性能较差, 因为事务管理器需要在多个数据源之间进行多次等待. 有一

java分布式事务

原文地址:http://blog.csdn.net/moonpure/article/details/52779794 在本系列先前的文章中,我们主要讲解了JDBC对本地事务的处理,本篇文章将讲到一个分布式事务的例子. 请通过以下方式下载github源代码: git clone https://github.com/davenkin/jta-atomikos-hibernate-activemq.git 本地事务和分布式事务的区别在于:本地事务只用于处理单一数据源事务(比如单个数据库),分布式事

分布式事务 解决方案

事务的概念来源于业务过程.在许多情况下我们都希望能够确保在一个过程中执行的所有操作是完全成功的.在集中式系统中,事务被广泛用于服务器端和数据库系统,控制数据的操作.随着分布式计算的发展,事务在分布式计算领域中也得到了广泛的应用,但是分布式系统架构中,分布式事务问题是一个绕不过去的挑战.而微服务架构的流行,让分布式事问题日益突出! 下面我们以电商购物支付流程中,在各大参与者系统中可能会遇到分布式事务问题的场景进行详细的分析! 如上图所示,假设三大参与平台(电商平台.支付平台.银行)的系统都做了分布

关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究[转]

1.XA XA是由X/Open组织提出的分布式事务的规范.XA规范主要定义了(全局)事务管理器(Transaction Manager)和(局部)资源管理器(Resource Manager)之间的接口.XA接口是双向的系统接口,在事务管理器(Transaction Manager)以及一个或多个资源管理器(Resource Manager)之间形成通信桥梁.XA之所以需要引入事务管理器是因为,在分布式系统中,从理论上讲(参考Fischer等的论文),两台机器理论上无法达到一致的状态,需要引入一

本地事务和分布式事务工作实践 【转】

一:从事务的历史说起 知已知彼,百战不败.想了解事务,我们从事务的历史说起. 在Windows平台上,事务的概念最开始出现在关系型数据库中,但是随着.net平台的发展,事务包括的的范围也越来越宽,先一睹为快, 在关系型数据库中的事务是通过begin transaction,rollback transaction, commit 等关键字来实现事务的. BEGIN TRANSACTION  UPDATE [dbo].[T_ACCOUNT] SET BALANCE = BALANCE + @amo

【故障处理】分布式事务ORA-01591错误解决

[故障处理]分布式事务ORA-01591错误解决 1  BLOG文档结构图       2  前言部分 2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① 分布式事务的简单概念         ② ORA-01591错误解决   Tips: ① 本文在ITpub(http://blog.itpub.net/26736162).博客园(http://www.cnblogs.com/lhrbest)和微信公众号(x