首页 技术 正文
技术 2022年11月11日
0 收藏 483 点赞 4,785 浏览 7477 个字

分布式事务是指操作多个数据库之间的事务,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>
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,497
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,910
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,744
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,498
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,135
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,300