分布式事务是指操作多个数据库之间的事务,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. 递归算法实现10进制到N进制的转换

    #include<iostream> using namespace std; int BaseTrans(int data,int B){ int s; ) ; //结束递归算法 s=d ...

  2. java核心技术记录之java术语

    术语名 缩写 解释 Java Development Kit JDK 编写java程序的程序员使用的软件 Java Runtime Environment JRE 运行java程序的用户使用的软件 S ...

  3. SDUT1479数据结构实验之栈:行编辑器

    先是普通的数组做法 #include<stdio.h> #include<string.h> int main() { ] ; while(~scanf("%s&qu ...

  4. 【转】Wireshark:“There are no interfaces on which a capture can be done ”

    linux环境下 两种解决方案:    第一种方法:使用root用户登陆        xiaoshancun@xiaoshancun-VM500:~$ sudo wireshark    第二种方法 ...

  5. s.charAt()

    public class ish{public static void main(String[]args){ String s="call me ishmae";System.o ...

  6. php动态滚动加载实例

    内容涉及:php.分页.jquery.div+css 实例下载:http://download.csdn.net/detail/roro5119/7373905 index.php <? //数 ...

  7. Ado.Net小练习03(省市联动)

    前台界面:          后台代码: namespace _04省市联动 {     public partial class Form1 : Form     {         public ...

  8. Linux 修改计算机名

    查看计算机名:在终端输入hostname 修改的话 hostname +计算机名(重启后失效) 要永久修改的话要修改配置文件/etc/sysconfig/network 修改hostname=你要改的 ...

  9. Android Include标签

    编程的世界有的时候很微妙,有的时候就好像是在解决一个哲学问题,Android开发的时候,所有的布局,颜色,等(其实这些都可以称之为资源,Android中的资源是指非代码部分,如图片.音频.视频.字符等 ...

  10. Case Study: Random Number Generation(翻译教材)

    很荣幸,经过三天的努力.终于把自己翻译的教材做完了,现在把它贴出来,希望能指出其中的不足.   Case Study: Random Number Generation Fig. 6.7  C++ 标 ...