spring 多数据源配置

spring 多数据源配置一般有两种方案:

1、在spring项目启动的时候直接配置两个不同的数据源,不同的sessionFactory。在dao 层根据不同业务自行选择使用哪个数据源的session来操作。

2、配置多个不同的数据源,使用一个sessionFactory,在业务逻辑使用的时候自动切换到不同的数据源,有一个种是在拦截器里面根据不同的业务现切换到不同的datasource;有的会在业务层根据业务来自动切换。但这种方案在多线程并发的时候会出现一些问题,需要使用threadlocal等技术来实现多线程竞争切换数据源的问题。

【本文暂时只讨论第一种方案】

spring多事务配置主要体现在db配置这块,配置不同的数据源和不同的session

1、一下贴出 spring-db.xml配置

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:tx="http://www.springframework.org/schema/tx"
  7. xsi:schemaLocation="
  8. http://www.springframework.org/schema/beans
  9. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  10. http://www.springframework.org/schema/context
  11. http://www.springframework.org/schema/context/spring-context-3.0.xsd
  12. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
  13. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
  14.  
  15. <bean id="test1DataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
  16. <property name="driverClassName" value="${database.test1.driverClassName}" />
  17. <property name="url" value="${database.test1.url}" />
  18. <property name="username" value="${database.test1.username}" />
  19. <property name="password" value="${database.test1.password}" />
  20. </bean>
  21.  
  22. <bean id="test2DataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
  23. <property name="driverClassName" value="${database.test2.driverClassName}" />
  24. <property name="url" value="${database.test2.url}" />
  25. <property name="username" value="${database.test2.username}" />
  26. <property name="password" value="${database.test2.password}" />
  27. </bean>
  28.  
  29. <bean id="test1SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  30. <property name="dataSource" ref="test1DataSource" />
  31. <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
  32. <property name="mapperLocations" value="classpath*:mybatis/mapper/*.xml" />
  33. </bean>
  34.  
  35. <bean id="test2SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  36. <property name="dataSource" ref="test2DataSource" />
  37. <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
  38. <property name="mapperLocations" value="classpath*:mybatis/mapper/*.xml" />
  39. </bean>
  40.  
  41. <bean id="test1TxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  42. <property name="dataSource" ref="test1DataSource"></property>
  43. </bean>
  44. <bean id="test2TxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  45. <property name="dataSource" ref="test2DataSource"></property>
  46. </bean>
  47.  
  48. <tx:annotation-driven transaction-manager="test2TxManager" />
  49. <tx:annotation-driven transaction-manager="test1TxManager" />
  50.  
  51. </beans>

2、dao层做了一个小的封装,将不同的SqlSessionFactory 注入到 SessionFactory,通过BaseDao来做简单的封装,封装不同库的基本增删改。dao实现层都集成于Basedao 这样的话,实现可以根据自己需要来选择不同的库来操作不同的内容。

session工厂

  1. package com.neo.dao;
  2.  
  3. import com.neo.entity.Entity;
  4.  
  5. public class BaseDao extends SessionFactory{
  6.  
  7. public void test1Update(Entity entity) {
  8. this.getTest1Session().update(entity.getClass().getSimpleName()+".update", entity);
  9. }
  10.  
  11. public void test2Update(Entity entity) {
  12. this.getTest2Session().update(entity.getClass().getSimpleName()+".update", entity);
  13. }
  14. }

BaseDao

  1. package com.neo.dao;
  2.  
  3. import com.neo.entity.Entity;
  4.  
  5. public class BaseDao extends SessionFactory{
  6.  
  7. public void test1Update(Entity entity) {
  8. this.getTest1Session().update(entity.getClass().getSimpleName()+".update", entity);
  9. }
  10.  
  11. public void test2Update(Entity entity) {
  12. this.getTest2Session().update(entity.getClass().getSimpleName()+".update", entity);
  13. }
  14. }

以上的配置在多数据源连接,正常的增删改都是没有问题的,但是遇到分布式的事务是就出问题:

测试代码:

  1. package com.neo.service.impl;
  2.  
  3. import javax.annotation.Resource;
  4.  
  5. import org.springframework.stereotype.Service;
  6. import org.springframework.transaction.annotation.Transactional;
  7.  
  8. import com.neo.dao.UserDao;
  9. import com.neo.dao.UserInformationsDao;
  10. import com.neo.entity.UserEntity;
  11. import com.neo.entity.UserInformationsEntity;
  12. import com.neo.service.UserService;
  13.  
  14. @Service
  15. public class UserServiceImpl implements UserService {
  16.  
  17. @Resource UserDao userDao;
  18. @Resource UserInformationsDao userInformationsDao;
  19.  
  20. @Override
  21. @Transactional
  22. public void updateUserinfo() {
  23.  
  24. UserEntity user=new UserEntity();
  25. user.setId(1);
  26. user.setUserName("李四4");
  27.  
  28. UserInformationsEntity userInfo=new UserInformationsEntity();
  29. userInfo.setUserId(1);
  30. userInfo.setAddress("陕西4");
  31.  
  32. userDao.updateUser(user);
  33. userInformationsDao.updateUserInformations(userInfo);
  34.  
  35. if(true){
  36. throw new RuntimeException("test tx ");
  37. }
  38. }
  39.  
  40. }

在service添加事务后,更新完毕抛出异常,test2更新进行了回滚,test1 数据更新没有回滚。

解决方案添加分布式的事务,Atomikos和spring结合来处理。

Atomikos多数据源的配置

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xmlns:tx="http://www.springframework.org/schema/tx"
  7. xsi:schemaLocation="
  8. http://www.springframework.org/schema/beans
  9. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  10. http://www.springframework.org/schema/context
  11. http://www.springframework.org/schema/context/spring-context-3.0.xsd
  12. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
  13. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
  14.  
  15. <bean id="test1DataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
  16. <property name="uniqueResourceName" value="test1"/>
  17. <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>
  18. <property name="xaProperties">
  19. <props>
  20. <prop key="url">${database.test1.url}</prop>
  21. <prop key="user">${database.test1.username}</prop>
  22. <prop key="password">${database.test1.password}</prop>
  23. </props>
  24. </property>
  25. <property name="minPoolSize" value="10" />
  26. <property name="maxPoolSize" value="100" />
  27. <property name="borrowConnectionTimeout" value="30" />
  28. <property name="testQuery" value="select 1" />
  29. <property name="maintenanceInterval" value="60" />
  30. </bean>
  31.  
  32. <bean id="test2DataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
  33. <property name="uniqueResourceName" value="test2"/>
  34. <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>
  35. <property name="xaProperties">
  36. <props>
  37. <prop key="url">${database.test2.url}</prop>
  38. <prop key="user">${database.test2.username}</prop>
  39. <prop key="password">${database.test2.password}</prop>
  40. </props>
  41. </property>
  42. <property name="minPoolSize" value="10" />
  43. <property name="maxPoolSize" value="100" />
  44. <property name="borrowConnectionTimeout" value="30" />
  45. <property name="testQuery" value="select 1" />
  46. <property name="maintenanceInterval" value="60" />
  47. </bean>
  48.  
  49. <bean id="test1SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  50. <property name="dataSource" ref="test1DataSource" />
  51. <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
  52. <property name="mapperLocations" value="classpath*:mybatis/mapper/*.xml" />
  53. </bean>
  54.  
  55. <bean id="test2SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  56. <property name="dataSource" ref="test2DataSource" />
  57. <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
  58. <property name="mapperLocations" value="classpath*:mybatis/mapper/*.xml" />
  59. </bean>
  60.  
  61. <!-- 分布式事务 -->
  62. <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">
  63. <property name="forceShutdown" value="true"/>
  64. </bean>
  65.  
  66. <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
  67. <property name="transactionTimeout" value="300"/>
  68. </bean>
  69.  
  70. <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
  71. <property name="transactionManager" ref="atomikosTransactionManager"/>
  72. <property name="userTransaction" ref="atomikosUserTransaction"/>
  73. </bean>
  74.  
  75. <tx:annotation-driven/>
  76.  
  77. </beans>

所有代码请参考这里:

https://github.com/ityouknow/spring-examples

spring 多数据源一致性事务方案的更多相关文章

  1. spring多数据源分布式事务的分析与解决方案

    一.概述 1.业务背景 对老系统进行重构合并,导致新系统需要同时对3个数据库进行管理.由于出现跨库业务,需要实现分布式事务. 2.开发环境 spring框架版本  4.3.10.RELEASE 持久层 ...

  2. Spring框架-经典的案例和demo,一些可以直接用于生产,使用atomikos来处理多数据源的一致性事务等

    Spring Examples Demo website:http://www.ityouknow.com/ 对Spring框架的学习,包括一些经典的案例和demo,一些可以直接用于生产. sprin ...

  3. QNJR-GROUP/EasyTransaction: 依赖于Spring的一个柔性事务实现,包含 TCC事务,补偿事务,基于消息的最终一致性事务,基于消息的最大努力交付事务交付QNJR-GROUP/EasyTransaction: 依赖于Spring的一个柔性事务实现,包含 TCC事务,补偿事务,基于消息的最终一致性事务,基于消息的最大努力交付事务交付

    QNJR-GROUP/EasyTransaction: 依赖于Spring的一个柔性事务实现,包含 TCC事务,补偿事务,基于消息的最终一致性事务,基于消息的最大努力交付事务交付 大规模SOA系统的分 ...

  4. Spring 多数据源事务配置问题

    2009-12-22 在SpringSide 3 中,白衣提供的预先配置好的环境非常有利于用户进行快速开发,但是同时也会为扩展带来一些困难.最直接的例子就是关于在项目中使用多个数据源的问题,似乎 很难 ...

  5. Spring 多数据源 @Transactional 注解事务管理

    在 Spring,MyBatis 下两个数据源,通过 @Transactional 注解 配置简单的事务管理 spring-mybatis.xml <!--******************* ...

  6. 基于注解的Spring多数据源配置和使用(非事务)

    原文:基于注解的Spring多数据源配置和使用 1.创建DynamicDataSource类,继承AbstractRoutingDataSource package com.rps.dataSourc ...

  7. 【spring boot】SpringBoot初学(7)– 多数据源及其事务

    前言 github: https://github.com/vergilyn/SpringBootDemo 代码位置: 参考: Spring Boot Reference Guide , §77.2 ...

  8. Spring 下,关于动态数据源的事务问题的探讨

    开心一刻 毒蛇和蟒蛇在讨论谁的捕猎方式最高效. 毒蛇:我只需要咬对方一口,一段时间内它就会逐渐丧失行动能力,最后死亡. 蟒蛇冷笑:那还得等生效时间,我只需要缠住对方,就能立刻致它于死地. 毒蛇大怒:你 ...

  9. 关于Spring Boot 多数据源的事务管理

    自己的一些理解:自从用了Spring Boot 以来,这近乎零配置和"约定大于配置"的设计范式用着确实爽,其实对零配置的理解是:应该说可以是零配置可以跑一个简单的项目,因为Spri ...

随机推荐

  1. ABP文档 - 本地化

    文档目录 本节内容: 简介 应用语言 本地化源 XML文件 注册XML本地化源 JSOn文件 注册JSON本地化源 资源文件 自定义源 获取一个本地文本 在服务端 在MVc控制器里 在MVC视图里 在 ...

  2. 探索ASP.NET MVC5系列之~~~5.缓存篇(页面缓存+二级缓存)

    其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...

  3. Emoji选项列表

    一.需要的前提文件 从网上下载Emoji的表情包,当然是png的图片,因为WPF不支持彩色的Emoji,所以,做列表的时候,需要用图片. 随着压缩包一起的还有一个Emoji.xml文件,文件的层级结构 ...

  4. 4.Android 打包时出现的Android Export aborted because fatal error were founds [closed]

    Android 程序开发完成后,如果要发布到互联网上供别人使用,就需要将自己的程序打包成Android 安装包文件(Android Package,APK),其扩展名为.apk.使用run as 也能 ...

  5. CSS知识总结(八)

    CSS常用样式 8.变形样式 改变元素的大小,透明,旋转角度,扭曲度等. transform : none | <transform-function> <transform-fun ...

  6. 利用for循环找出1000以内的质数

    var n=0; for(var i=2;i<=1000;i++){  var zhishu=true;  for(var j=2;j<i;j++){    if(i%j==0){    ...

  7. 中国CIO最关心的八大问题(下)

    中国CIO最关心的八大问题(下) 从调研数据还可以看出,在企业级IT建设与投资上,CIO们并非是一群狂热的技术信徒,他们更多的是从企业发展阶段.信息化程度.技术成熟度.ROI等方面进行综合评估. 五. ...

  8. Android中的沉浸式状态栏效果

    无意间了解到沉浸式状态栏,感觉贼拉的高大上,于是就是试着去了解一下,就有了这篇文章.下面就来了解一下啥叫沉浸式状态栏.传统的手机状态栏是呈现出黑色条状的,有的和手机主界面有很明显的区别.这一样就在一定 ...

  9. i++、++i 、i--、--i

    总结: i++ 先用后加, ++i先加后用: i--先用后减, --i先减后用: //int i = 1; //Console.WriteLine(i);//1 //Console.WriteLine ...

  10. Oracle 11g必须开启的服务及服务详细介绍

    转自:http://www.educity.cn/shujuku/404120.html 成功安装Oracle  11g数据库后,你会发现自己电脑运行速度会变慢,配置较低的电脑甚至出现非常卡的状况,通 ...