Spring分布式事务实现
分布式事务是指操作多个数据库之间的事务,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分布式事务实现的更多相关文章
- Spring分布式事务实现概览
分布式事务,一直是实现分布式系统过程中最大的挑战.在只有单个数据源的单服务系统当中,只要这个数据源支持事务,例如大部分关系型数据库,和一些MQ服务,如activeMQ等,我们就可以很容易的实现事务. ...
- Spring分布式事务
[如何实现XA式.非XA式Spring分布式事务] [http://www.importnew.com/15812.html] 在JavaWorld大会上,来自SpringSource的David S ...
- spring分布式事务学习笔记
最近项目中使用了分布式事务,本文及接下来两篇文章总结一下在项目中学到的知识. 分布式事务对性能有一定的影响,所以不是最佳的解决方案,能通过设计避免最好尽量避免. 分布式事务(Distributed t ...
- 如何实现XA式、非XA式Spring分布式事务
Spring应用的几种事务处理机制 Java Transaction API和XA协议是Spring常用的分布式事务机制,不过你可以选择选择其他的实现方式.理想的实现取决于你的应用程序使用何种资源,你 ...
- 非XA式Spring分布式事务
Spring应用的几种事务处理机制 Java Transaction API和XA协议是Spring常用的分布式事务机制,不过你可以选择选择其他的实现方式.理想的实现取决于你的应用程序使用何种资源,你 ...
- Spring分布式事务实现(适用于spring-tx 2.5)
http://log-cd.iteye.com/blog/807607 分布式事务是指操作多个数据库之间的事务,spring的org.springframework.transaction.jta.J ...
- spring分布式事务控制
应用场景问题描述解决方法多数据源配置单元测试第一种方法:最大努力一次提交模式第二种方法:最大努力一次提交模式 但使用ChainedTransactionManagerChainedTransactio ...
- spring分布式事务学习笔记(1)
此文已由作者夏昀授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 分布式事务对性能有一定的影响,所以不是最佳的解决方案,能通过设计避免最好尽量避免. 分布式事务(Distrib ...
- Spring 分布式事务详解
在学习分布式事务的过程中会遇到以下关键名词: 相关名词: XA :XA规范的目的是允许多个资源(如数据库,应用服务器,消息队列,等等)在同一事务中访问,这样可以使ACID属性跨越应用程序而保持有效.X ...
随机推荐
- Sublime Text 3配置与vim模式(待完整)
Sublime Text 3通过设置默认值与用户值的方式,来进行配置.默认值不允许更改,用户值是用户进行配置.同一属性,当用户值存在时,默认值就无效.打开Preference,如图: 先贴下我的Set ...
- SDUT1586 计算组合数(组合数)
这个题数据量小,不容易超时. #include<stdio.h> long long fac(int n) { ; ; i <= n ; i++) { m = i*m; } retu ...
- Android service的开启和绑定,以及调用service的方法
界面: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android= ...
- Android ActionBar下拉选项
package com.example.actionBarTest.actionBarList; import android.app.ActionBar; import android.app.Ac ...
- cojs 简单的01串 题解报告
题意显然是求n位二进制串中不大于其逆序串,取反串,逆序取反串的所有串按字典序排序后的第k个 由于n很小,k很大所以我们可以考虑逐位确定 问题转化为了求方案数,这显然是可以用数位DP做的 设f[len] ...
- BZOJ 1982 Moving Pebbles
首先我们假设只有两堆, 容易发现当且仅当两堆相等时,先手必败 否则先手必胜 然后我们猜测一下原因: ->当两堆相等时,无论先手怎么做,后手总能使两堆相等,且必败态为0,0 推广一下: 当所有的石 ...
- SELinux开启与关闭
SELinux是「Security-Enhanced Linux」的简称,是美国国家安全局「NSA=The National Security Agency」 和SCC(Secure Computin ...
- 利用PhantomJS搭建Highcharts export服务
利用PhantomJS搭建Highcharts export服务 一直在使用Highcharts做web图表的展示, 但是当发送定时的报表邮件的遇到了这个问题. 为了保证邮件图表和web页图表样式一致 ...
- 结巴分词标注兼容_ICTCLAS2008汉语词性标注集
计算所汉语词性标记集Version 3.0制订人:刘群 张华平 张浩计算所汉语词性标记集... 10. 说明... 11. 名词 (1个一类,7个二类,5个三类) 22. 时间词(1个一类,1个二类) ...
- C#6.0 VS2015
https://msdn.microsoft.com/en-us/library/hh156499(v=vs.140).aspx This page lists key feature names f ...