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

Spring分布式事务实现的更多相关文章

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

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

  2. Spring分布式事务

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

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

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

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

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

  5. 非XA式Spring分布式事务

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

  6. Spring分布式事务实现(适用于spring-tx 2.5)

    http://log-cd.iteye.com/blog/807607 分布式事务是指操作多个数据库之间的事务,spring的org.springframework.transaction.jta.J ...

  7. spring分布式事务控制

    应用场景问题描述解决方法多数据源配置单元测试第一种方法:最大努力一次提交模式第二种方法:最大努力一次提交模式 但使用ChainedTransactionManagerChainedTransactio ...

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

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

  9. Spring 分布式事务详解

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

随机推荐

  1. POJ 1060 Modular multiplication of polynomials(多项式的加减乘除,除法转化成减法来求)

    题意:给出f(x),g(x),h(x)的 (最高次幂+1)的值,以及它们的各项系数,求f(x)*g(x)/h(x)的余数. 这里多项式的系数只有1或0,因为题目要求:这里多项式的加减法是将系数相加/减 ...

  2. 【leetcode】Median of Two Sorted Arrays(hard)★!!

    There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted ...

  3. SNAT

    http://blog.chinaunix.net/uid-2628744-id-2454879.html

  4. MySQL数据导出导入【转】

    MySQL基础 关于MySQL数据导出导入的文章,目的有二: 1.备忘 2.供开发人员测试 工具 mysqlmysqldump 应用举例 导出 导出全库备份到本地的目录 mysqldump -u$US ...

  5. addListener添加事件监听器,第三个参数useCapture (Boolean) 的作用

    addEventListener 有三个参数:第一个参数表示事件名称(不含 on,如 "click"):第二个参数表示要接收事件处理的函数:第三个参数为 useCapture,本文 ...

  6. Apache HTTP Server安装

    http://blog.csdn.net/wqmain/article/details/8941759 很清楚,很详细,配置连行号都有.下载的时候直接点击链接即可.

  7. 关于Linux的时间与时区

    转:http://linux.chinaunix.net/techdoc/beginner/2007/06/22/960790.shtml 首先要说明的是我的系统是fedora,其他系统可能不完全相同 ...

  8. 使用List,Dictionary加载数据库中的数据

    情景描述:数据库中有一张设备表,字段DWDM存放的是各个厂编号,字段ZNBH存放的是设备编号.其中DWDM跟ZNBH是一对多的关系.需要将数据库中的值加载到List<Dictionary< ...

  9. PHP Warning: date(): It is not safe to rely on the system's timezone settings.

    OSSEC安装结束后运行,运行以下命令却抛错 cat /opt/ossec/logs/alerts/alerts.log 具体抛错内容: ** Alert 1468897672.2164786: ma ...

  10. DAO设计模式 -- 使用数据库连接类连接MySql数据库并实现添加用户

    1. DAO简介    DAO设计模式是属于J2EE数据库层的操作,使用DAO设计模式可以简化大量代码,增强程序的可移植性. 2. DAO各部分详解    DAO设计模式包括5个重要的部分,分别为数据 ...