最近搭建架构,碰到JTA和事务Transaction的问题,在此做个总结:
架构:Mybatis+ Spring
技术:spring的AbstractRoutingDataSource和JTA
老规矩,先贴代码,在讲原理,刚开始的时候不使用JTA,代码如下:
/**
* DataSource上下文句柄,通过此类设置需要访问的对应数据源
*
*/
public class DataSourceContextHolder {
/**
* DataSource上下文,每个线程对应相应的数据源key
*/
public static final ThreadLocal contextHolder = new ThreadLocal();
public static void setDataSourceType(String dataSourceType)
{
contextHolder.set(dataSourceType);
}
public static String getDataSourceType()
{
return contextHolder.get();
}
public static void clearDataSourceType()
{
contextHolder.remove();
}
}
/**
* 动态数据源
*
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSourceType();
}
}
spring中配置如下:
<!-- 配置数据源 -->
<bean id="ds1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
lazy-init="false">
<property name="driverClassName" value="${jdbc.ds1.driverClassName}" />
<property name="url" value="${jdbc.ds1.url}" />
<property name="username" value="${jdbc.ds1.username}" />
<property name="password" value="${jdbc.ds1.password}" />
<property name="initialSize" value="5" />
<property name="maxActive" value="10" />
<property name="maxWait" value="60000" />
<property name="poolPreparedStatements" value="true" />
</bean>
<bean id="ds2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
lazy-init="false">
<property name="driverClassName" value="${jdbc.ds2.driverClassName}" />
<property name="url" value="${jdbc.ds2.url}" />
<property name="username" value="${jdbc.ds2.username}" />
<property name="password" value="${jdbc.ds2.password}" />
<property name="initialSize" value="5" />
<property name="maxActive" value="10" />
<property name="maxWait" value="60000" />
<property name="poolPreparedStatements" value="true" />
</bean>
<!-- 动态数据源 -->
<bean id="dataSource" class="xxx.DynamicDataSource">
<property name="targetDataSources">
<map>
<entry key="ds1" value-ref="ds1" />
<entry key="ds2" value-ref="ds2" />
</map>
</property>
<property name="defaultTargetDataSource" ref="ds1" />
</bean>
<!-- 事务管理 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven/>
<!-- myBatis配置 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatis-config.xml" />
<property name="dataSource" ref="dataSource" />
</bean>
<!-- DAO层由 MapperScannerConfigurer自动生成mapper bean -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="xxx.mapper" />
</bean>
因为每个Service目前只可能访问一个DataSource,所以在调用Service的时候,调用DataSourceContextHolder.setDataSourceType(key)(key可以为ds1,ds2),
就可以动态切换数据源了(当然最好用AOP思想,技术上spring + AspectJ,在每个Service需要的方法切上一刀),
而且对于spring的@Transactional事务管理是起作用的
OK,按照这种模式,如果Service可能访问多个库,就将DataSourceTransactionManager换成JtaTransactionManager
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager" />
<tx:annotation-driven transaction-manager="transactionManager" />
当然,Datasource换成JNDI获取
<!-- 创建数据源。 -->
<bean id="ds1" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>ds1</value>
</property>
<property name="resourceRef">
<value>true</value>
</property>
</bean>
<bean id="ds2" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>ds2</value>
</property>
<property name="resourceRef">
<value>true</value>
</property>
</bean>
在spring的@Transactional事务管理中,那是死活无法切换数据源
由于内容有点多,这个技术总结分为两部分。
分享到:
相关推荐
springboot + mybatis-plus + database+ 多数据源 + redis + hutool 框架干净,没有其他冗余的成分; 配置了MP的代码生成器,意见生成代码,节省开发时间! 可用于各种定时任务处理,各种夸库操作, 多数据源支持...
spring3+hibernate4+maven+junit 多库多数据源实现,非常好的一个学习多数据分点管理,分别连接不同类型数据源的方法
什么时候才用的到配置多数据源??当我们用不同数据库存放不同数据的时候。这个时候我们整个工程并不是只用一个数据库,所以,要配置多个,在具体的场景应用具体的数据源。
spring mybatis atomikos 分布式事务 自己写的小demo 包含依赖包
springboot多数据源切换mysql+sql server,该事例代码demo,下载下来就能使用,使用工具idea,自行安装mysql和sql server
支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。支持数据库敏感配置信息 加密(可自定义) ENC()。支持每个数据库独立初始化表结构schema和数据库database。支持无数据源启动,支持懒加载...
纯spring多数据库事务,是spring和atomikos组合使用。有spring注解设置数据源,由atomikos负责数据源管理,负责事务管理。追求零配置。大大简化工作量。供参考
springMVC+ansj中文分词+多线程+mybatis+redis+多库等等
一个基于springboot的快速集成多数据源的启动器简介dynamic-datasource-spring-boot-starter是一个基于springboot的快速集成多数据源的启动器。其支持Jdk 1.7 +,SpringBoot 1.4.x 1.5.x 2.xx。文件| 文献资料|特性...
支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。 支持数据库敏感配置信息 加密(可自定义) ENC()。 支持每个数据库独立初始化表结构schema和数据库database。 支持无数据源启动,支持懒加载...
支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。 支持数据库敏感配置信息 加密(可自定义) ENC()。 支持每个数据库独立初始化表结构schema和数据库database。 支持无数据源启动,支持懒加载...
springboot整合多数据源 实现多库读写的例子 包含源码
NULL 博文链接:https://wiselyman.iteye.com/blog/1150495
springboot双数据库定时同步,可以是mysql,SqlServer
介绍多库系统和数据库系统的概念、方法、理论
在公司开发的过程中,用到主从库的切换,于是就想自己动手实现一个可以实现多库之间的随意切 换。于是该项目就产生了!该项目基于spring2.0.1才添加的的AbstractRutingDataSource类,同时利 用AspectJ项目实现aop...
文档中方案不能彻底解决多库分布式事务数据一致性问题,但能大大降低数据不一致的概率,带来的副作用是数据库连接占用时间会增长,吞吐量会降低。对于一致性与吞吐量的折衷,还需要业务架构师谨慎权衡折衷。
金多库管软件 不打会用 专业人士玩去吧
mysql数据库全文查找,查询所有数据库中包含指定字符的数据。 一、支持功能: 1、支持所有数据库查询字符串,或者指定一个或者多个数据库查询字符串; 2、支持本地使用或者指定远程数据库地址; 3、支持命令行指定...
多库俄罗斯方块C#版本, 有注释,呵呵。