项目进行读写分离及分库分表,在一个业务中,在一个事务中处理时候将切换多个数据源,需要保证同一事务多个数据源数据的一致性。此处使用atomikos来实现:最后附源码:

1:spring3.0之后不再支持jtom[jta]了,第三方开源软件atomikos(http://www.atomikos.com/)来实现.

2:org.springframework.transaction.jta.JotmFactoryBean类,spring-tx-2.5.6.jar中有此类,spring-tx-3.0.0.RELEASE.jar之后没有此类。

3:atomikos事务控制框架,其中看到有3种数据源,分别是,SimpleDataSourceBean,AtomikosDataSourceBean,AtomikosNonXADataSourceBean。

a:SimpleDataSourceBean: 这个是最简单地数据源配置,需要配置XA驱动。

b:AtomikosDataSourceBean:  分布式数据源,Atomikos实现的数据源,需要配置XA驱动,推荐此配置,可以配置连接池的信息。

c:AtomikosNonXADataSourceBean: 非分布式数据源,该数据源配置需要普通JDBC的驱动,可以配置连接池:

4:Atomikos支持XA(全局事务)和NON-XA(非全局事务),NON-XA[nonxadatasource]效率高于XA.XA事务往往是包括多个数据源的全局事务,非XA是单个数据源的.

5:XA连接是一个JTA事务中的参与者。XA连接不支持JDBC的自动提交特性。也就是说应用程序不必在xadatasource[XA]连接上调用java.sql.Connection.commit()或java.sql.Connection.rollback();而应用程序应该使用UserTransaction.begin(),UserTransaction.commit()和UserTransaction.rollback().

看看pom.xml依赖:

org.springframework

spring-tx

4.2.5.RELEASE

javax.transaction

jta

1.1

com.atomikos

atomikos-util

4.0.2

com.atomikos

transactions

4.0.2

com.atomikos

transactions-jta

4.0.2

com.atomikos

transactions-jdbc

4.0.2

com.atomikos

transactions-api

4.0.2

cglib

cglib-nodep

3.2.2

1:AtomikosDataSourceBean[XA(全局事务)]数据源配置datasource-context.xml:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"

xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:aop="http://www.springframework.org/schema/aop"

xsi:schemaLocation="http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.0.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-4.0.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-4.0.xsd" default-lazy-init="true">

配置主-从数据源信息

${jdbc.driverClassName}

${master.jdbc.url}

${jdbc.password}

${jdbc.username}

0

20

0

60000

${validationQuery}

false

false

true

true

1800

true

mergeStat

${jdbc.driverClassName}

${slave.jdbc.url}

${jdbc.password}

${jdbc.username}

0

20

0

60000

${validationQuery}

false

false

true

true

1800

true

mergeStat

2:spring主配置文件spring-context.xml:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.2.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-3.2.xsd

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

3:数据源配置参数database.properties:

#mysql-Used to verify the effectiveness of the database connection

validationQuery=SELECT 1

jdbc.initialSize=5

jdbc.maxActive=20

jdbc.maxWait=60000

jdbc.poolPreparedStatements=false

jdbc.poolMaximumIdleConnections=0

jdbc.driverClassName=org.gjt.mm.mysql.Driver

jdbc.xaDataSourceClassName=com.alibaba.druid.pool.xa.DruidXADataSource

#jdbc.xaDataSourceClassName=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource

#1.tms business. 2.The db level optimization,data concurrency,desirable.

master.jdbc.url=jdbc:mysql://your ip:3306/master?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull

slave.jdbc.url=jdbc:mysql://your ip:3306/slave?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull

jdbc.username=username

jdbc.password=password4:mybatis的配置mybatis-context.xml:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:aop="http://www.springframework.org/schema/aop"

xsi:schemaLocation="http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.0.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-4.0.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-4.0.xsd" default-lazy-init="true">

MyBatis的数据库持久层配置/配置主-从数据源

配置mybatis-config(此代码,只为测试分布式事务,并不涉及真实的业务!!!):

mybatis-config-master.xml:

mybatis-config-slave.xml

5:Mapper的管理及注入,为mybatis的dao层mapper接口注入[绑定]sqlSessionFactory:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:aop="http://www.springframework.org/schema/aop"

xsi:schemaLocation="http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.0.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-4.0.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-4.0.xsd" default-lazy-init="true">

MyBatis为不同的mapper注入sqlSessionFactory

6:atomikos事务配置transaction-context.xml:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"

xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:aop="http://www.springframework.org/schema/aop"

xsi:schemaLocation="http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.0.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-4.0.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-4.0.xsd" default-lazy-init="true">

配置事物

true

7:配置jta启动参数在src下,最后追加详细:

com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory

com.atomikos.icatch.console_file_name = /home/logs/tx/tx.out.log

com.atomikos.icatch.log_base_name = txlog

com.atomikos.icatch.tm_unique_name = com.atomikos.spring.jdbc.tm

com.atomikos.icatch.console_log_level=DEBUG8:代码(部分不涉及代码已删除):

a:mybatis的mapper和dao接口[MemberMapper/MemberInfoMapper]:

package com.tx.dao;

import com.tx.entity.Member;

public interface MemberMapper {

int insert(Member record);

}

package com.tx.dao;

import com.tx.entity.MemberInfo;

public interface MemberInfoMapper {

int insert(MemberInfo record);

}

id, username, password, status

insert into member (id, username, password,

status)

values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR},

#{status,jdbcType=TINYINT})

id, nickname, realname, age

insert into member_info (id, nickname, realname,

age)

values (#{id,jdbcType=INTEGER}, #{nickname,jdbcType=VARCHAR}, #{realname,jdbcType=VARCHAR},

#{age,jdbcType=TINYINT})

b:服务层接口和实现:

package com.tx.sevice;

import com.tx.entity.Member;

import com.tx.entity.MemberInfo;

public interface MemberService {

boolean registerMember(Member member, MemberInfo memberInfo);

}

package com.tx.sevice.impl;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.tx.dao.MemberInfoMapper;

import com.tx.dao.MemberMapper;

import com.tx.entity.Member;

import com.tx.entity.MemberInfo;

import com.tx.sevice.MemberService;

@Service("memberService")

public class MemberServiceImpl implements MemberService {

//log

private static final Logger LOG = LoggerFactory.getLogger(MemberServiceImpl.class);

@Autowired

private MemberMapper memberMapper;

@Autowired

private MemberInfoMapper memberInfoMapper;

@Override

public boolean registerMember(Member member, MemberInfo memberInfo) {

boolean resRegister = false;

try {

if(memberMapper.insert(member) != 1){

throw new RuntimeException("注册用户:Member表数据插入不一致.");

}

if(memberInfoMapper.insert(memberInfo) != 1){

throw new RuntimeException("注册用户:MemberInfo表数据插入不一致.");

}

resRegister = true;

} catch (Exception e) {

LOG.info("注册用户:数据库保存异常." + e.getMessage(), e);

throw new RuntimeException("注册用户:数据库保存异常");

}

return resRegister;

}

}c:junit测试代码:

package com.tx.test;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.test.context.ContextConfiguration;

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.tx.entity.Member;

import com.tx.entity.MemberInfo;

import com.tx.sevice.MemberService;

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = {"classpath:spring-context.xml","classpath:datasource-context.xml",

"classpath:mybatis-context.xml","classpath:mapper-context.xml","classpath:transaction-context.xml"})

public class JTATest {

//log

private static final Logger LOG = LoggerFactory.getLogger(JTATest.class);

@Autowired

private MemberService memberService;

@Test

public void testRegister(){

Member member = new Member();

member.setId(2);

member.setUsername("童可可");

member.setPassword("12345678");

member.setStatus((byte)0);

MemberInfo memberInfo = new MemberInfo();

memberInfo.setId(2);

memberInfo.setAge((byte)25);

memberInfo.setNickname("keke");

memberInfo.setRealname("童可可");

if(memberService.registerMember(member, memberInfo)){

LOG.info("##用户注册成功");

}else{

LOG.info("##用户注册失败");

}

}

}注:通过主键重复可以测试回滚,数据没问题,正常提交不同数据库!log4j和web.xml和sql,其他代码:Spring实现数据库读写分离/spring事务配置解释

效果图:

执行前,master数据库:

执行前,slave数据库:

执行后,master数据库:

执行后,slave数据库:

spring-tx-2.5.6.jar和spring-tx-3.0.0.RELEASE.jar目录:

jta.properties启动参数:

# SAMPLE PROPERTIES FILE FOR THE TRANSACTION SERVICE

# THIS FILE ILLUSTRATES THE DIFFERENT SETTINGS FOR THE TRANSACTION MANAGER

# UNCOMMENT THE ASSIGNMENTS TO OVERRIDE DEFAULT VALUES;

# Required: factory implementation class of the transaction core.

# NOTE: there is no default for this, so it MUST be specified!

#

com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory

# Set base name of file where messages are output

# (also known as the 'console file').

#

com.atomikos.icatch.console_file_name = tm.out

# Size limit (in bytes) for the console file;

# negative means unlimited.

#

# com.atomikos.icatch.console_file_limit=-1

# For size-limited console files, this option

# specifies a number of rotating files to

# maintain.

#

# com.atomikos.icatch.console_file_count=1

# Set the number of log writes between checkpoints

#

# com.atomikos.icatch.checkpoint_interval=500

# Set output directory where console file and other files are to be put

# make sure this directory exists!

#

# com.atomikos.icatch.output_dir = ./

# Set directory of log files; make sure this directory exists!

#

# com.atomikos.icatch.log_base_dir = ./

# Set base name of log file

# this name will be used as the first part of

# the system-generated log file name

#

com.atomikos.icatch.log_base_name = tmlog

# Set the max number of active local transactions

# or -1 for unlimited.

#

# com.atomikos.icatch.max_actives = 50

# Set the default timeout (in milliseconds) for local transactions

#

# com.atomikos.icatch.default_jta_timeout = 10000

# Set the max timeout (in milliseconds) for local transactions

#

# com.atomikos.icatch.max_timeout = 300000

# The globally unique name of this transaction manager process

# override this value with a globally unique name

#

com.atomikos.icatch.tm_unique_name = tm

# Do we want to use parallel subtransactions? JTA's default

# is NO for J2EE compatibility

#

# com.atomikos.icatch.serial_jta_transactions=true

# If you want to do explicit resource registration then

# you need to set this value to false.

#

# com.atomikos.icatch.automatic_resource_registration=true

# Set this to WARN, INFO or DEBUG to control the granularity

# of output to the console file.

#

com.atomikos.icatch.console_log_level=INFO

# Do you want transaction logging to be enabled or not?

# If set to false, then no logging overhead will be done

# at the risk of losing data after restart or crash.

#

# com.atomikos.icatch.enable_logging=true

# Should two-phase commit be done in (multi-)threaded mode or not?

# Set this to false if you want commits to be ordered according

# to the order in which resources are added to the transaction.

#

# NOTE: threads are reused on JDK 1.5 or higher.

# For JDK 1.4, thread reuse is enabled as soon as the

# concurrent backport is in the classpath - see

# http://mirrors.ibiblio.org/pub/mirrors/maven2/backport-util-concurrent/backport-util-concurrent/

#

# com.atomikos.icatch.threaded_2pc=false

# Should shutdown of the VM trigger shutdown of the transaction core too?

#

# com.atomikos.icatch.force_shutdown_on_vm_exit=false

分布式事务操作之Spring+JTA可参照: http://www..com/wangyong/p/4174326.html

Atomikos 中文说明文档:http://blog..net/sun8288/article/details/8674016

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

springmvc atomikos mysql数据源_Spring多数据源分布式事务管理/springmvc+spring+atomikos[jta]+druid+mybatis...相关推荐

  1. Spring-Boot + Atomikos 实现跨库的分布式事务管理

    一.何为事务 定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作成功,要么都不成功. 其必须遵循的四个原则(ACID): 原子性(Atomicity -- 美 [ˌætəˈ ...

  2. spring事务隔离级别、传播行为以及spring+mybatis+atomikos实现分布式事务管理

    1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功.其必须遵循四个原则(ACID). 原子性(Atomicity):即事务是不可分割的最小工作单 ...

  3. 分布式事务管理Atomikos

    目录 XA协议 Atomikos介绍 atomikos_demo Spring对分布式事务的支持 基于spring实现 事务执行流程 XA协议 用于支持单个服务操作多个服务源,XA是由X/Open组织 ...

  4. 基于MySQL和DynamoDB的强一致性分布式事务实践

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 后台回复"k8s",可领取k8s资料 在单体应用向微服 ...

  5. mysql xid原理_MySQL数据库分布式事务XA实现原理分析

    [IT168 技术]MySQL XA原理 MySQL XA分为两类,内部XA与外部XA;内部XA用于同一实例下跨多个引擎的事务,由大家熟悉的Binlog作为协调者;外部XA用于跨多MySQL实例的分布 ...

  6. mysql xa 实现_MySQL数据库分布式事务XA的实现原理分析

    1 原理 关于MySQL数据库的分布式事务XA,分布式事务实现的原理,可见[3];关于MySQL XA的说明,可见[1][2]. MySQL XA分为两类,内部XA与外部XA;内部XA用于同一实例下跨 ...

  7. 解读金融高频交易不出错的金手指:分布式事务管理

    本文分享自华为云社区<华为云分布式事务管理DTM:6大特性解决云上微服数据一致性>,原文作者:灰灰哒. 云原生2.0时代,微服务架构下如何保证数据的一致性是非常重要的一个课题.4月8日,在 ...

  8. SpringBoot+Nacos+Seata实现Dubbo分布式事务管理

    SpringBoot+Nacos+Seata实现Dubbo分布式事务管理 https://www.shangmayuan.com/a/a3ba056126ba45db9b8dfd5b.html 源码下 ...

  9. SpringBoot+Zookeeper+Seata实现Dubbo分布式事务管理

    面我已经写过一篇SpringBoot+Nacos+Seata实现Dubbo分布式事务管理的文章,今天为什么还要写这篇呢,是因为好多公司还在用Zookeeper作为Dubbo的注册中心和配置中心在大规模 ...

最新文章

  1. 明略科技完成2亿美元E+轮融资,中俄投资基金领投,腾讯、弘卓资本等跟投
  2. mysql问题举例_MySql问题总结
  3. nw.js启动时白屏
  4. Request的学习笔记(属Servlet学习课程)
  5. 深度学习图像超分辨率最新综述:从模型到应用
  6. PAT乙级(1007 素数对猜想)
  7. 正则表达式的使用,python正则匹配一个话题标签
  8. 【Android】LMK 工作机制
  9. python35安装教程_python详细安装教程,非常值得看的一篇文章
  10. Object-C---gt;Swift之(十一)属性观察者
  11. 甘肃教师学苑2020文章代码_【重磅通知】甘肃省电化教育中心 关于聘任教育信息化研究员的通知...
  12. 修改电脑微信提示音+dll文件编辑器
  13. qq互联登录授权php配置,网站接入QQ登录(QQ互联)php版的流程
  14. python如何设置当前工作路径?
  15. 微软云+Servlet实现图片上传接口
  16. 类和对象10:对象访问方法
  17. Pytorch CPU Tensor与GPU Tensor的运算速度对比测试
  18. POJO和PO的概念,区别
  19. HANA学习季(一) :HANA的基本概念
  20. Win电脑敬业签团队便签怎么修改记事本文字颜色?

热门文章

  1. GPS软件接收机matlab程序学习笔记(一)
  2. ERROR exceptions Error 111 connecting ERROR basehttp 124
  3. 面试可以问面试官哪些问题?这些问题需要弄清楚
  4. 零基础小白学Node-RED(05):串口节点的使用
  5. Spring boot 启动图片
  6. json数据处理实战:Kafka+Flume+Morphline+Solr+Hue数据组合索引
  7. python numpy pandas 书 全_夯基固本学Python—Numpy与Pandas
  8. Nacos-Client服务注册
  9. 求指点,求指点,求指点
  10. css实现向右的箭头