`
caicai1230231
  • 浏览: 23705 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

基于spring,Atomikos,mybatis的分布式动态数据源JTA实现

阅读更多

本文的几个关键词,分布式数据源,数据源的动态寻找,分布式事务JTA实现。
     对于一些较大规模的应用,单个数据源是无法支撑起庞大的用户量,需要引入多数据源,水平层面进行分库分表,降低单个DB的负载。接下来,我们程序里里面需 要管理不同数据源之前的程序调用,保证功能是WORK的。另外,跨库就意味着之前单DB的事务就失效了,所以J2EE提出了JTA,分布式的事务管理,往 简单了说,就是2步提交(two phase),比单步提交更苛刻。实际上他有两个容器来管理,一个是资源管理器,一个是事务管理。小伙伴们可以发现,这是一个环环相扣的过程。想解决一个 问题,你就得解决这几个相关的问题。以下代码,我也是参考了前辈们的思想,进行了改造。

    第一步:XA数据源定义
     选定义一个抽象的父类源,这样子类可以直接继承

  
 1  <!-- 两个数据源的功用配置,方便下面直接引用 -->
 2      <bean id="abstractXADataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init"
 3              destroy-method="close" abstract="true">
 4         <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>
 5         <property name="poolSize" value="10" />
 6         <property name="minPoolSize" value="10"/>
 7         <property name="maxPoolSize" value="30"/>
 8         <property name="borrowConnectionTimeout" value="60"/>
 9         <property name="reapTimeout" value="20"/>
10         <!-- 最大空闲时间 -->
11         <property name="maxIdleTime" value="60"/>
12         <property name="maintenanceInterval" value="60" />
13         <property name="loginTimeout" value="60"/>
14         <property name="logWriter" value="60"/>
15         <property name="testQuery">
16             <value>select 1</value>
17         </property>
18         
19     </bean>
20 
   A源
     
 1 <!-- 配置第一个数据源 -->
 2     <bean id="dataSource_a" parent="abstractXADataSource">
 3     <!-- value只要两个数据源不同就行,随便取名 -->
 4         <property name="uniqueResourceName" value="mysql/sitestone" />
 5         <property name="xaDataSourceClassName"
 6             value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
 7         <property name="xaProperties">
 8             <props>
 9                 <prop key="URL">${jdbc.url.spider}</prop>
10                 <prop key="user">${jdbc.username}</prop>
11                 <prop key="password">${jdbc.password}</prop>
12             </props>
13         </property>
14     </bean>
   
B   源

   
 1 <!-- 配置第二个数据源-->
 2     <bean id="dataSource_b" parent="abstractXADataSource">
 3 <!-- value只要两个数据源不同就行,随便取名 -->
 4         <property name="uniqueResourceName" value="mysql/sitesttwo" />
 5         <property name="xaDataSourceClassName"
 6             value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
 7         <property name="xaProperties">
 8             <props>
 9                <prop key="URL">${jdbc_tb.url.spider}</prop>
10                 <prop key="user">${jdbc_tb.username}</prop>
11                 <prop key="password">${jdbc_tb.password}</prop>
12             </props>
13         </property>
14     </bean>

基于SPRING的AbstractRoutingDataSource动态数据路由定义
1   <bean name="dynamicDatasource" class="com.***.spring.datasource.CustomerDatasource">
2         <property name="targetDataSources">
3             <map>
4                 <entry key="ds_1" value-ref="dataSource_a"/>
5                 <entry key="ds_2" value-ref="dataSource_b"/>
6             </map>
7         </property>
8         <property name="defaultTargetDataSource" ref="dataSource_a"    />
9     </bean>

我这里是使用MYBATIS来进行ORM映射,配置如下

 1  <bean id="sqlSessionFactorya" class="org.mybatis.spring.SqlSessionFactoryBean">
 2         <property name="dataSource" ref="dataSource_a"/>
 3          <property name="typeAliasesPackage" value="com.****.spring.dschange.bean" />
 4          <!-- mapper和resultmap配置路径 --> 
 5         <property name="mapperLocations">
 6             <list>
 7                 <!-- 表示在com.**目录下的任意包下的resultmap包目录中,以-resultmap.xml或-mapper.xml结尾所有文件 --> 
 8                 <value>classpath:com/***/spring/dschange/mapper/ShopMapper.xml</value>
 9             </list>
10         </property>
11     </bean>
12     <bean id="sqlSessionFactoryb" class="org.mybatis.spring.SqlSessionFactoryBean">
13         <property name="dataSource" ref="dataSource_b"/>
14          <property name="typeAliasesPackage" value="com.****.spring.dschange.bean" />
15           <!-- mapper和resultmap配置路径 --> 
16         <property name="mapperLocations">
17             <list>
18                 <!-- 表示在com.***目录下的任意包下的resultmap包目录中,以-resultmap.xml或-mapper.xml结尾所有文件 --> 
19                 <value>classpath:com/***/spring/dschange/mapper/ShopMapper.xml</value>
20             </list>
21         </property>
22     </bean>

接下来,一个比较关键的地方是对MYBATIS的CustomSqlSessionTemplate的重写,主要是引入动态数据源sqlSessionFactory。针对不同的数据库,调用其对应的会话工厂,这对JTA是否启用,比较重要。

 1  @Override
 2     public SqlSessionFactory getSqlSessionFactory() {
 3  
 4         SqlSessionFactory targetSqlSessionFactory = targetSqlSessionFactorys.get(DataSourceKeyHolder.getDataSourceKey());
 5         if (targetSqlSessionFactory != null) {
 6             return targetSqlSessionFactory;
 7         } else if (defaultTargetSqlSessionFactory != null) {
 8             return defaultTargetSqlSessionFactory;
 9         } else {
10             Assert.notNull(targetSqlSessionFactorys, "Property 'targetSqlSessionFactorys' or 'defaultTargetSqlSessionFactory' are required");
11             Assert.notNull(defaultTargetSqlSessionFactory, "Property 'defaultTargetSqlSessionFactory' or 'targetSqlSessionFactorys' are required");
12         }
13         return this.sqlSessionFactory;
14     }
XML配置
 1  <!-- 配置自定义的SqlSessionTemplate模板,注入相关配置 -->
 2     <bean id="sqlSessionTemplate" class="com.amos.spring.mybatis.CustomSqlSessionTemplate" scope="prototype">
 3         <constructor-arg ref="sqlSessionFactorya" />
 4         <property name="targetSqlSessionFactorys">
 5             <map>     
 6                 <entry value-ref="sqlSessionFactorya" key="ds_1"/>
 7                 <entry value-ref="sqlSessionFactoryb" key="ds_2"/>
 8             </map> 
 9         </property>
10     </bean>

扫描配置

1  <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
 1     <!-- jta -->
 2     <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
 3         init-method="init" destroy-method="close">
 4         <property name="forceShutdown">
 5             <value>true</value>
 6         </property>
 7     </bean>
 8  
 9     <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
10         <property name="transactionTimeout" value="300" />
11     </bean>
12  
13     <bean id="springTransactionManager"
14         class="org.springframework.transaction.jta.JtaTransactionManager">
15         <property name="transactionManager">
16             <ref bean="atomikosTransactionManager" />
17         </property>
18         <property name="userTransaction">
19             <ref bean="atomikosUserTransaction" />
20         </property>
21     </bean>
22  <tx:annotation-driven transaction-manager="springTransactionManager" proxy-target-class="true" />
2         <property name="basePackage" value="com.****.spring.dschange.mapper" />
3         <property name="sqlSessionTemplateBeanName" value="sqlSessionTemplate"/>
4         <property name="markerInterface" value="com.*****.spring.dschange.mapper.SqlMapper"/>
5     </bean>


最后就是JTA的实现配置

 1     <!-- jta -->
 2     <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
 3         init-method="init" destroy-method="close">
 4         <property name="forceShutdown">
 5             <value>true</value>
 6         </property>
 7     </bean>
 8  
 9     <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
10         <property name="transactionTimeout" value="300" />
11     </bean>
12  
13     <bean id="springTransactionManager"
14         class="org.springframework.transaction.jta.JtaTransactionManager">
15         <property name="transactionManager">
16             <ref bean="atomikosTransactionManager" />
17         </property>
18         <property name="userTransaction">
19             <ref bean="atomikosUserTransaction" />
20         </property>
21     </bean>
22  <tx:annotation-driven transaction-manager="springTransactionManager" proxy-target-class="true" />

以上,XML配置相关的东西已经完成。
具体的代码,请点击GITHUB查看https://github.com/igool/spring-jta-mybatis

1
1
分享到:
评论
2 楼 caicai1230231 2015-09-29  

我也想过,这是2步提交,确实有性能上的问题。我之前在网站上看过一篇文单,我打算接下来用这个来实现,哈哈。谢谢了。http://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with-and-without-xa.html
1 楼 cywhoyi 2015-09-28  
生产环境别这么干,存在的弱点很多。
厂商间通过实现XA接口,本身存在着各种问题
当你要自定义的很多时候,依赖于它不靠谱
不如写路由

相关推荐

    spring mybatis atomikos 多库分布式事务demo

    本示例“spring mybatis atomikos 多库分布式事务demo”聚焦于如何在Spring与MyBatis框架下利用Atomikos实现跨数据库的分布式事务管理。 首先,Spring是一个广泛应用的开源框架,提供了丰富的功能,包括依赖注入、...

    java+spring+mybatis+mysql+RuoYi-atomikos-实现分布式事务.zip

    本项目"java+spring+mybatis+mysql+RuoYi-atomikos-实现分布式事务.zip"是一个基于若依(RuoYi)框架改造的多模块分布式事务解决方案,它利用了Atomikos这一强大的分布式事务管理器。以下将详细解析这个项目的知识点...

    Spring+MyBatis+Atomikos实现JTA分布式事务

    本文将深入探讨如何使用Spring、MyBatis和Atomikos实现JTA分布式事务。 首先,让我们理解JTA的概念。Java Transaction API(JTA)是Java EE规范之一,用于处理分布式环境中的事务。它允许应用程序在不同的资源管理...

    使用Spring+atomikos实现分布式事务

    总结,结合Spring和Atomikos可以有效地处理分布式事务,确保跨多个数据源的操作在事务性语义下执行。配置包括设置Atomikos事务管理器、数据源以及事务属性,然后在业务逻辑中利用Spring的`@Transactional`注解来管理...

    Spring Boot + Druid + Mybatis + Atomikos 配置多数据源 并支持分布式事务

    本教程将探讨如何利用Spring Boot、Druid、Mybatis以及Atomikos来配置多数据源并实现分布式事务。 首先,Spring Boot是Java生态系统中的一个流行框架,它简化了设置和配置过程,使得开发人员可以快速启动新项目。在...

    Springboot+Atomikos+Jpa+Mysql实现JTA分布式事务

    Atomikos通过实现JTA规范,允许应用程序在不同的数据源之间进行跨系统事务处理。 JPA是Java平台上的标准ORM(Object-Relational Mapping)框架,用于管理和持久化Java对象到关系数据库。它提供了一种抽象层,使得...

    Spring boot+Atomikos+JTA+Hibernate+mybatis+MySQL实现分布式事务+多数据源

    本案例主要探讨如何利用Spring Boot、Atomikos、JTA(Java Transaction API)、Hibernate以及MyBatis,结合MySQL数据库,实现一个跨数据源的分布式事务解决方案。 首先,Spring Boot是一个基于Spring框架的快速开发...

    spring、mybatis、atomikos实现多数据源事务demo

    Spring框架,MyBatis持久层框架,以及Atomikos这样的分布式事务协调器共同工作,可以帮助我们实现复杂的多数据源事务处理。这个“spring、mybatis、atomikos实现多数据源事务demo”就是为了解决这一问题而设计的。 ...

    Spring+Mybatis+Atomikos实现JAVA初始化并控制多个数据源+分布式事务

    总的来说,这个DEMO旨在帮助开发者理解如何在Java应用中实现多数据源和分布式事务,涉及到的核心技术包括Spring的多数据源支持、Mybatis的持久层操作以及Atomikos的事务协调。通过实践这个DEMO,开发者可以深入掌握...

    Spring Boot+Druid+Mybatis实现JTA分布式事务

    本教程将详细讲解如何使用Spring Boot、Druid和Mybatis来实现JTA(Java Transaction API)分布式事务。这是一项高级技术,它允许在多数据库环境或者微服务架构中进行一致性的数据操作。 首先,让我们了解什么是JTA...

    springboot + mybatis + atomikos 多数据源分布式事物管理

    Spring Boot、MyBatis 和 Atomikos 的结合提供了一种解决方案,用于处理多数据源的分布式事务管理。以下是对这个主题的详细阐述。 首先,Spring Boot 是一个基于 Spring 框架的轻量级开发工具,它简化了配置过程并...

    spring+mybatis+atomikos配置文件及相关包(最新版)

    Atomikos可以与Spring无缝集成,通过实现XAResource接口,它能够协调不同的数据源,确保在分布式环境下的ACID(原子性、一致性、隔离性和持久性)特性。 配置Spring、MyBatis和Atomikos进行分布式事务处理通常涉及...

    maven springboot jta mybatis 分布式事物

    综上所述,这个项目是一个利用 Maven 构建的 Spring Boot 应用,它整合了多数据源、JTA 来处理分布式事务,使用 MyBatis 作为持久层框架,并且集成了某种模板引擎来生成动态页面。这样的设计使得项目具备处理大规模...

    spring、mybatis、atomikos实现DB2、Mysql多数据源事务demo

    本示例中的"spring、mybatis、atomikos实现DB2、Mysql多数据源事务demo"提供了一个实用的框架,演示了如何在Spring框架中结合MyBatis持久层框架以及Atomikos事务管理器来处理来自DB2和MySQL两个不同数据库的数据源...

    非Maven基于SSM+Atomikos的分布式事务处理案例源码

    7. 数据源配置:由于涉及到多数据源,你需要为每个数据源创建单独的Atomikos数据源,并在Spring中声明这些数据源。 8. 事务边界设定:在业务代码中,通过`@Transactional`注解标记方法,声明该方法需要在事务内执行...

    springboot+mybatis+jta+atomikos解决多数据源事务问题.pdf

    本篇文档主要讲述如何使用Spring Boot结合MyBatis、JTA(Java Transaction API)以及Atomikos实现多数据源的事务管理。 ### Spring Boot框架 Spring Boot是Spring家族中的一个全新框架,用于简化新Spring应用的...

    spring+mybatis+atomikos配置所需包跟配置文件

    4. 配置MyBatis:MyBatis需要与Spring集成,使用Spring管理SqlSessionFactory,同时需要配置使用Atomikos的数据源。 ```xml &lt;bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"&gt; ...

    spring+mybatis+atomikos配置文件及相关包.rar

    本篇文章将深入探讨如何在Spring框架中结合Mybatis和Atomikos进行分布式事务管理的配置与集成。Atomikos是一款强大的开源事务处理系统,它支持JTA(Java Transaction API),可以为我们的应用程序提供分布式事务解决...

    分布式事务操作之Spring+JTA+mybatis源码

    本话题主要聚焦于如何在Spring框架中结合Java Transaction API (JTA) 和 MyBatis 实现分布式事务管理。下面我们将详细探讨相关知识点。 1. **分布式事务**:在分布式系统中,事务处理跨越多个资源或服务,例如...

    Spring多数据源分布式事务管理

    在这个场景下,Atomikos作为一款开源的JTA(Java Transaction API)实现,常被用来处理Spring中的分布式事务。 首先,让我们来了解一下Spring多数据源配置。在Spring中,我们可以通过DataSourceProxy和...

Global site tag (gtag.js) - Google Analytics