spring编程式事务⽀持多数据源事务控制
项⽬框架是jdbcTemplat+spring+struts2,项⽬需求是需要在⼀个⽅法中实现多个数据库的访问,并实现多数据源的事务控制。可直接复制使⽤。
下⾯直接贴代码和解决⽅案
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
xmlns:xsi="/2001/XMLSchema-instance"
xsi:schemaLocation="/schema/beans
/schema/beans/spring-beans-4.0.xsd">
<bean id="datasource2016" class="org.apachemons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@*:1521/orcl" />
<property name="username" value="****" />
<property name="password" value="***" />
</bean>
<bean id="datasource1" class="org.apachemons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@*:1521/orcl" />
<property name="username" value="***" />
<property name="password" value="***" />
</bean>
<bean id="jdbcTemplate" class="org.JdbcTemplate">
<property name="dataSource" ref="datasource2016" />
</bean>
<bean id="jdbcTemplate1" class="org.JdbcTemplate">
<property name="dataSource" ref="datasource1" />
</bean>
<bean id="bgdDataSource1" class="com.bgd.platform.util.dao.BgdDataSource">
<property name="jdbcTemplate" ref="jdbcTemplate" />
<property name="transactionTemplate" ref="transactionTemplate" />
<property name="abstractBgdDBSql" ref="abstractBgdDBSql" />
</bean>
<bean id="bgdDataSourcefk" class="com.bgd.platform.util.dao.BgdDataSource">
<property name="jdbcTemplate" ref="jdbcTemplate1" />
<property name="transactionTemplate" ref="transactionTemplate1" />
<property name="abstractBgdDBSql" ref="abstractBgdDBSql" />
</bean>
<bean id="bgdDataSource" class="com.bgd.platform.util.dao.BgdDataSourceMulti">
<property name="defaultDataSource">
<ref bean="bgdDataSource1" />
</property>
<property name="dataSources">
<map>
<entry key="ql">
<ref bean="bgdDataSource1" />
</entry>
<entry key="fk">
<ref bean="bgdDataSourcefk" />
</entry>
</map>
</property>
</bean>
<bean id="bgdDataSourceKylin" class="com.bgd.platform.util.dao.BgdDataSourceKylin">
<bean id="bgdDataSourceKylin" class="com.bgd.platform.util.dao.BgdDataSourceKylin">
<property name="dataSourceKylin" ref="dataSourcekylin"/>
</bean>
<bean id="abstractBgdDBSql" class="com.bgd.platform.util.dao.BgdDBSqlOracle">
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource2016"/>
</bean>
<bean id="transactionManager1" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource1"/>
</bean>
<bean id="transactionTemplate" class="ansaction.support.TransactionTemplate"
>
<property name="transactionManager" ref="transactionManager" />
</bean>
<bean id="transactionTemplate1" class="ansaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager1" />
</bean>
<bean id="transactionProxy" class="ansaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="target" ref="bgdDataSource"/>
<property name="transactionAttributes">
<props>
<!--
transactionAttributes属性可以设置事务处理的⽅式,事务隔离级别,是否只读三个属性,⽤逗号隔开事务隔离级别各数据库系统不完全⽀持,⼀般不设置,⽤默认的即可
事务处理选项有如下⼏个:(前⾯2个常⽤)
PROPAGATION_REQUIRED -需要事务处理。如果当前不存在事务环境,则创建⼀个
PROPAGATION_SUPPORTS -如果当前存在事务环境,则作为其中的⼀部分。如果不存在,则按⾮事务⽅式执⾏ PROPAGATION_REQUIRES_NEW -需要事务处理。并总是开启⼀个新事务。如果已经存在事务环境,则挂起之 PROPAGATION_MANDATORY -执⾏到指定⽅法时,必须已经存在事务环境,否则出错
PROPAGATION_NEVER -不⽀持事务操作,如果存在事务环境会出错
PROPAGATION_NOT_SUPPORTED -不⽀持事务操作。如果存在事务,则挂起
-->
<prop key="*">PROPAGATION_REQUIRED,-Exception</prop>
</props>
</property>
</bean>
<bean id="transactionProxy1" class="com.bgd.platform.util.dao.TransactionManagerIntercetor">
<property name="transactionManagerBeanNames">
<list>
<value>transactionManager</value>
<value>transactionManager1</value>
</list>
</property>
<property name="target" ref="bgdDataSource1"/>
</bean>
<bean id="transactionProxyMulti" class="org.springframework.aop.framework.ProxyFactoryBean" >
<property name="interceptorNames">
<list>
<value>transactionProxy1</value>
</list>
</property>
</bean>
</beans>
<bean name="menuManageBo" class="com.bgd.platform.sys.user.service.MenuManageService">
<property name="bgdDataSource" ref="bgdDataSource" />
</bean>
<bean id="menuManageService" parent="transactionProxyMulti">
<property name="target">
<ref bean="menuManageBo" />
</property>
</bean>
<bean name="menuManageAction" class="com.bgd.platform.sys.user.action.MenuManageAction">
<property name="menuManageService" ref="menuManageService"/>
</bean>
代理多个数据源代码:
package com.bgd.platform.util.dao;
import com.bgd.platform.util.service.SpringContextUtil;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import ansaction.TransactionStatus;
import ansaction.support.DefaultTransactionDefinition;
import java.util.List;
import java.util.Stack;
public class TransactionManagerIntercetor implements MethodInterceptor {
private Object target;
public void setTarget(Object target) {
this.target = target;
}
private List<String> transactionManagerBeanNames;
public void setTransactionManagerBeanNames(List transactionManagerBeanNames) {jdbctemplate查询一条数据
}
private boolean openTransaction(Stack<DataSourceTransactionManager> dataSourceTransactionManagerStack,
Stack<TransactionStatus> transactionStatuStack) {
for (String beanName : transactionManagerBeanNames) {
DataSourceTransactionManager dataSourceTransactionManager = (DataSourceTransactionManager) Bean(beanName);
TransactionStatus transactionStatus = Transaction(new DefaultTransactionDefinition());
transactionStatuStack.push(transactionStatus);
dataSourceTransactionManagerStack.push(dataSourceTransactionManager);
}
return true;
}
private void commit(Stack<DataSourceTransactionManager> dataSourceTransactionManagerStack, Stack<TransactionStatus> transactionStatuStack){ while (!dataSourceTransactionManagerStack.isEmpty()) {
dataSourceTransactionManagerStack.pop()mit(
transactionStatuStack.pop());
}
}
private void rollback(Stack<DataSourceTransactionManager> dataSourceTransactionManagerStack,
Stack<TransactionStatus> transactionStatuStack){
while (!dataSourceTransactionManagerStack.isEmpty()) {
dataSourceTransactionManagerStack.pop().rollback(
dataSourceTransactionManagerStack.pop().rollback(
transactionStatuStack.pop());
}
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Stack<DataSourceTransactionManager> dataSourceTransactionManagerStack = new Stack<DataSourceTransactionManager>(); Stack<TransactionStatus> transactionStatuStack = new Stack<TransactionStatus>();
Object retVal = null;
try {
if (!openTransaction(dataSourceTransactionManagerStack, transactionStatuStack)) {
return null;
}
retVal = invocation.proceed();
commit(dataSourceTransactionManagerStack, transactionStatuStack);
} catch(Exception e) {
rollback(dataSourceTransactionManagerStack, transactionStatuStack);
throw e;
}
return retVal;
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论