`

对多数据源进行aop声明式事务管理

阅读更多
当在对数据库表进行横向切分(将一个表的数据拆分为到多个数据库中)之后, 在操作数据库的时候需要路由到合适的数据源, 这里我参照了Spring对多数据源的路由处理方式(http://blog.springsource.com/2007/01/23/dynamic-datasource-routing). 具体实现如下.
首先是TransactionManager的配置:
<?xml version="1.0" encoding="gb2312"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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.0.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
	<bean id="db1Tx"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource">
            <ref bean="db1" />
		</property>
	</bean>

	<bean id="db2Tx"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource">
			<ref bean="db2" />
		</property>
	</bean>

	<bean id="dbcTx"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource">
		      <ref bean="dbc" />
		</property>
	</bean>

	<bean id="routingTransactionManager" class="com.mysoft.manager.impl.RoutingTransactionManager">
		<property name="targetTransactionManagers">
			<map value-type="org.springframework.transaction.PlatformTransactionManager">
				<entry key="db1" value-ref="db1Tx" />
				<entry key="db2" value-ref="db2Tx" />
				<entry key="dbc" value-ref="dbcTx" />
			</map>
		</property>
	</bean>

	<!--     配置事务回滚的场景   -->
	<tx:advice id="txAdvice" transaction-manager="routingTransactionManager">
		<tx:attributes>
            		<tx:method name="*" rollback-for="java.lang.Exception"/>
		</tx:attributes>
	</tx:advice>
	
	<!--   指定那些类的哪些方法参与事务   -->
	<aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.mysoft.manager.Manager1.publish(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.mysoft.manager.Manager2.audit(..))"/>
	</aop:config>
</beans>

这里用到了spring的tx和aop标签, 都是spring的参考手册中的典型配置. 当调用指定的packageName.method(..)方法的时候, 将采用事务拦截, 如果在对该方法的调用过程中出现了任何异常将导致事务回滚.

接下来就是路由的问题, 其中RoutingContextHolder类内部使用一个ThreadLocal类用来指定db1, db2, db3等key值, RoutingTransactionManager类则根据当前线程中的key值取得对应的tx.
/**
* 用来存储路由到指定tx的Context
 * 
 * @since 2009-10-28 下午01:54:46
 */
@SuppressWarnings("unchecked")
public class RoutingContextHolder<T> {
    private static final ThreadLocal contextHolder = new ThreadLocal();

    public static <T> void setContext(T context) {
        Validate.notNull(context, "必须指定路由的context");
        contextHolder.set(context);
    }

    public static <T> T getContext() {
        return (T) contextHolder.get();
    }
}

/**
* 根据给定的路由规则来路由到合适的tx类
 * 
 * @since 2009-10-28 下午01:34:11
 * @see RoutingContextHolder
 */
public class RoutingTransactionManager implements PlatformTransactionManager {
    private Map<Object, PlatformTransactionManager> targetTransactionManagers =
            new HashMap<Object, PlatformTransactionManager>();

    /**
     * 根据给定的规则获取指定的tx
     * 
     * @return
     */
    protected PlatformTransactionManager getTargetTransactionManager() {
        Object context = RoutingContextHolder.getContext();
        Validate.notNull(context, "必须指定路由的context");
        return targetTransactionManagers.get(context);
    }

    public void setTargetTransactionManagers(Map<Object, PlatformTransactionManager> targetTransactionManagers) {
        this.targetTransactionManagers = targetTransactionManagers;
    }

    public void commit(TransactionStatus status) throws TransactionException {
        getTargetTransactionManager().commit(status);
    }

    public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
        return getTargetTransactionManager().getTransaction(definition);
    }

    public void rollback(TransactionStatus status) throws TransactionException {
        getTargetTransactionManager().rollback(status);
    }
}

其调用代码如下:
// 指定tx的路由context
RoutingContextHolder.setContext("db1");
return manager1.publish(item);
3
1
分享到:
评论

相关推荐

    基于 SpringBoot 多数据源 动态数据源 主从分离 快速启动器 支持分布式事务.zip

    Spring框架为开发提供了一系列的解决方案,比如利用控制反转的核心特性,并通过依赖注入实现控制反转来实现管理对象生命周期容器化,利用面向切面编程进行声明式的事务管理,整合多种持久化技术管理数据访问,提供...

    "优雅的SSM框架"进行完善(页面分离+nginx负载均衡+tomcat集群)

    Spring(IOC DI AOP 声明式事务处理) SpringMVC(支持Restful风格) Hibernate Validate(参数校验) Mybatis(最少配置方案) Quartz时间调度 统一的异常处理 Redis缓存(ProtoStuff序列化) Redis Sentinel主从高...

    java ssm开发的生产管理ERP系统

    - Spring(IOC DI AOP 声明式事务处理) - SpringMVC(支持Restful风格) - Hibernate Validator(参数校验) - Mybatis(最少配置方案) - shiro权限控制,结合ajax实现了异步认证与异步授权,同时实现了细粒度的...

    JAVA制造装备物联及生产管理(ERP)系统源码

    Spring(IOC DI AOP 声明式事务处理) SpringMVC(支持Restful风格) Hibernate Validator(参数校验) Mybatis(最少配置方案) shiro权限控制,结合ajax实现了异步认证与异步授权,同时实现了细粒度的...

    基于SSM框架的生产管理ERP系统源码+数据库+项目文档,含计划进度、设备管理、工艺监控、物料监控、人员监控、质量监控、系统管理

    Spring(IOC DI AOP 声明式事务处理) SpringMVC(支持Restful风格) Hibernate Validator(参数校验) Mybatis(最少配置方案) shiro权限控制,结合ajax实现了异步认证与异步授权,同时实现了细粒度的权限动态...

    MF00331-JAVA制造装备物联生产管理(ERP)源码.zip

    Spring(IOC DI AOP 声明式事务处理) SpringMVC(支持Restful风格) Hibernate Validator(参数校验) Mybatis(最少配置方案) shiro权限控制,结合ajax实现了异步认证与异步授权,同时实现了细粒度的权限动态...

    erp源码-ssm+easyUI+mysql+maven+shiro

    erp项目 基于ssm+easyUI+mysql+maven+shiro开发 本系统实现目标如下: ## 项目技术架构(Spring+SpringMVC+Mybatis) ## - Maven - Spring(IOC DI AOP 声明式事务处理) - SpringMVC(支持Restful风格) - Hibernate...

    SSM框架教程Spring+SpringMVC+MyBatis全覆盖_Java热门框架视频教程

    7、Spring的声明式事务控制 8、SpringMVC的介绍及其快速入门 9、SpringMVC的数据请求和响应 10、SpringMVC的异常处理及其拦截器 11、MyBatis简介及其入门 12、MyBatis的配置文件详解 13、MyBatis的多表操作 适用...

    qh-erp-ssm

    - Spring(IOC DI AOP 声明式事务处理) - SpringMVC(支持Restful风格) - Hibernate Validator(参数校验) - Mybatis(最少配置方案) - shiro权限控制,结合ajax实现了异步认证与异步授权,同时实现了细粒度的...

    erp完整源码-ssm+easyUI+mysql+maven+shiro

    erp项目 基于ssm+easyUI+mysql+maven+shiro开发 本系统实现目标如下: ## 项目技术架构(Spring+SpringMVC+Mybatis) ## - Maven - Spring(IOC DI AOP 声明式事务处理) - SpringMVC(支持Restful风格) - Hibernate...

    Spring 2.0 开发参考手册

    9.7. 选择编程式事务管理还是声明式事务管理 9.8. 与特定应用服务器集成 9.8.1. BEA WebLogic 9.8.2. IBM WebSphere 9.9. 公共问题的解决方案 9.9.1. 对一个特定的 DataSource 使用错误的事务管理器 9.10. 更多...

    Spring中文帮助文档

    9.7. 选择编程式事务管理还是声明式事务管理 9.8. 与特定应用服务器集成 9.8.1. IBM WebSphere 9.8.2. BEA WebLogic 9.8.3. Oracle OC4J 9.9. 常见问题的解决方法 9.9.1. 对一个特定的 DataSource 使用了错误...

    Spring API

    9.7. 选择编程式事务管理还是声明式事务管理 9.8. 与特定应用服务器集成 9.8.1. IBM WebSphere 9.8.2. BEA WebLogic 9.8.3. Oracle OC4J 9.9. 常见问题的解决方法 9.9.1. 对一个特定的 DataSource 使用了错误...

    spring chm文档

    9.7. 选择编程式事务管理还是声明式事务管理 9.8. 与特定应用服务器集成 9.8.1. BEA WebLogic 9.8.2. IBM WebSphere 9.9. 公共问题的解决方案 9.9.1. 对一个特定的 DataSource 使用错误的事务管理器 9.10. 更多...

    Spring-Reference_zh_CN(Spring中文参考手册)

    9.7. 选择编程式事务管理还是声明式事务管理 9.8. 与特定应用服务器集成 9.8.1. BEA WebLogic 9.8.2. IBM WebSphere 9.9. 公共问题的解决方案 9.9.1. 对一个特定的 DataSource 使用错误的事务管理器 9.10. 更多的...

    第24次课-1 Spring与Hibernate的整合

    方便的事务管理:Spring提供的声明式事务处理可以全面有效地处理事务。 异常包装:Spring能够包装Hibernate的异常,使开发者可以选择恰当的层来处理异常。 24.2 管理SessionFactory Hibernate的SessionFactory,是...

    Spring.3.x企业应用开发实战(完整版).part2

    9.6 使用注解配置声明式事务 9.6.1 使用@Transactional注解 9.6.2 通过AspectJ LTW引入事务切面 9.7 集成特定的应用服务器 9.7.1 BEA WebLogic 9.7.2 BEA WebLogic 9.8 小结 第10章 Spring的事务管理难点剖析 10.1 ...

    Spring3.x企业应用开发实战(完整版) part1

    9.6 使用注解配置声明式事务 9.6.1 使用@Transactional注解 9.6.2 通过AspectJ LTW引入事务切面 9.7 集成特定的应用服务器 9.7.1 BEA WebLogic 9.7.2 BEA WebLogic 9.8 小结 第10章 Spring的事务管理难点剖析 10.1 ...

    Spring面试题

    1.面向切面编程提供声明式事务管理 2.spring支持用户自定义的切面 面向切面编程(aop)是对面向对象编程(oop)的补充, 面向对象编程将程序分解成各个层次的对象,面向切面编程将程序运行过程分解成各个切面。 ...

    springboot.zip

    具体整合jsp,freemarker,banner,全局捕获异常,log4j日志,aop,lombok,异步执行,多环境配置,mybatis,声明式事务,多数据源,mybatis分业,热部署,Undertow容器, 搭建springboot监控中心,整合redis,solr,activemq,email,...

Global site tag (gtag.js) - Google Analytics