Spring分布式事务实现(适用于spring-tx 2.5)
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及实现
- 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>
最后,补充一下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)的更多相关文章
- spring分布式事务学习笔记
最近项目中使用了分布式事务,本文及接下来两篇文章总结一下在项目中学到的知识. 分布式事务对性能有一定的影响,所以不是最佳的解决方案,能通过设计避免最好尽量避免. 分布式事务(Distributed t ...
- Spring分布式事务实现概览
分布式事务,一直是实现分布式系统过程中最大的挑战.在只有单个数据源的单服务系统当中,只要这个数据源支持事务,例如大部分关系型数据库,和一些MQ服务,如activeMQ等,我们就可以很容易的实现事务. ...
- Spring分布式事务
[如何实现XA式.非XA式Spring分布式事务] [http://www.importnew.com/15812.html] 在JavaWorld大会上,来自SpringSource的David S ...
- 分布式事务操作之Spring+JTA
什么是分布式事务?在网上找了一段比较容易理解的"定义". 分布式事务是指事务的参与者.支持事务的服务器.资源管理器以及事务管理器分别位于分布系统的不同节点之上,在两个或多个网络计算 ...
- Spring分布式事务实现
分布式事务是指操作多个数据库之间的事务,spring的org.springframework.transaction.jta.JtaTransactionManager,提供了分布式事务支持.如果使用 ...
- spring分布式事务学习笔记(1)
此文已由作者夏昀授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 分布式事务对性能有一定的影响,所以不是最佳的解决方案,能通过设计避免最好尽量避免. 分布式事务(Distrib ...
- atomikos实现多数据源支持分布式事务管理(spring、tomcat、JTA)
原文链接:http://iteye.blog.163.com/blog/static/1863080962012102945116222/ Atomikos TransactionsEssenti ...
- Spring 分布式事务详解
在学习分布式事务的过程中会遇到以下关键名词: 相关名词: XA :XA规范的目的是允许多个资源(如数据库,应用服务器,消息队列,等等)在同一事务中访问,这样可以使ACID属性跨越应用程序而保持有效.X ...
- 如何实现XA式、非XA式Spring分布式事务
Spring应用的几种事务处理机制 Java Transaction API和XA协议是Spring常用的分布式事务机制,不过你可以选择选择其他的实现方式.理想的实现取决于你的应用程序使用何种资源,你 ...
随机推荐
- HW6.16
import java.util.Arrays; public class Solution { public static void main(String[] args) { int[] arra ...
- CP-ABE环境配置
本环境配置步骤参考互联网: 1.安装m4 sudo apt-get install m4 2.安装gmphttp://gmplib.org/ 下载gmplib ./configure make ma ...
- 软件开发中的单一职责(转至INFOQ)
最近在实践微服务化过程中,对其“单一职责”原则深有体会.那么只有微服务化才可以单一职责,才可以解耦吗?答案是否定的. 单一职责原则是这样定义的:单一的功能,并且完全封装起来. 我们做后端Java开发的 ...
- 怎样让你的代码更好的被JVM JIT Inlining
好书推荐:Effective Java中文版(第2版) JVM JIT编译器优化技术有近100中,其中最最重要的方式就是内联(inlining).方法内联可以省掉方法栈帧的创建,方法内联还使让JIT编 ...
- C/C++流程图生成器 C转流程图【worldsing笔记】
此版本仅供学习,请大家支持正版软件!! AutoFlowChart v3.1软件下载: http://url.cn/OUK17C 支持导出:word.visio.图片格式. 例如:main.c # ...
- [css]display: table-cell,用div做分列布局
table-cell我们却能用得到,而且是用它来干一件很重要的事情——多列布局. 多列布局在css中有多重要就不用我说了吧,传统模式下大家都使用float来解决这一问题,但是float写出来的东西代码 ...
- Swif基本语法以及与OC比较三
(未 经 博 主 同 意,不 得 转 载 !) ------------------------华丽分割线----------------------- // // main.swift ...
- mysql之select+五种子句的理解
select 可以包含很复杂,很丰富的逻辑,最能考验一个人的逻辑思维能力和sql语句的掌握程度,我是这么认为,以前的很多次面试几乎都死在它手上,所以才有了今天的这篇日志,下定决心把它学好. where ...
- Ps切图学习
1.切图的原文件格式为psd,用ps工具打开 2.鼠标点击需要切的图片,会自动选中图层: 3.选择需要切图的图层,右键复制图层 宽高必须为2的倍数 文件-存储为web和设备所用格式 预设选择为png- ...
- C#-datagridview隐藏行头
在进行datagridview的设置的过程中,常常会遇到需要设定datagridview1的行头显示,这就需要用到datagridview的属性: RowHeadersVisible属性设置为fals ...