设为首页 收藏本站
查看: 1769|回复: 0

[经验分享] 多库数据源深入分析(Mybatis+ Spring + JTA)(一)

[复制链接]

尚未签到

发表于 2016-11-27 10:46:31 | 显示全部楼层 |阅读模式
  最近搭建架构,碰到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事务管理中,那是死活无法切换数据源
  由于内容有点多,这个技术总结分为两部分。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-306111-1-1.html 上篇帖子: Mybatis深入剖析 下篇帖子: mybatis学习入门二、Association一对一关联
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表