Spring多数据源分布式事务管理/springmvc+spring+atomikos[jta]+druid+mybatis

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 项目进行读写分离及分库分表,在一个业务中,在一个事务中处理时候将切换多个数据源,需要保证同一事务多个数据源数据的一致性。此处使用atomikos来实现:最后附源码: 1:spring3.0之后不再支持jtom[jta]了,第三方开源软件atomikos(http://www.atomikos.com/)来实现.  2:org.springframework.transaction.jt

项目进行读写分离及分库分表,在一个业务中,在一个事务中处理时候将切换多个数据源,需要保证同一事务多个数据源数据的一致性。此处使用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依赖:

		<!-- transaction -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>4.2.5.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>javax.transaction</groupId>
			<artifactId>jta</artifactId>
			<version>1.1</version>
		</dependency>
		<dependency>
			<groupId>com.atomikos</groupId>
			<artifactId>atomikos-util</artifactId>
			<version>4.0.2</version>
		</dependency>
		<dependency>
			<groupId>com.atomikos</groupId>
			<artifactId>transactions</artifactId>
			<version>4.0.2</version>
		</dependency>
		<dependency>
			<groupId>com.atomikos</groupId>
			<artifactId>transactions-jta</artifactId>
			<version>4.0.2</version>
		</dependency>
		<dependency>
			<groupId>com.atomikos</groupId>
			<artifactId>transactions-jdbc</artifactId>
			<version>4.0.2</version>
		</dependency>
		<dependency>
			<groupId>com.atomikos</groupId>
			<artifactId>transactions-api</artifactId>
			<version>4.0.2</version>
		</dependency>
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib-nodep</artifactId>
			<version>3.2.2</version>
		</dependency>
1:AtomikosDataSourceBean[XA(全局事务)]数据源配置datasource-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	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">
	<description>配置主-从数据源信息</description>
	<!-- com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean -->
 	<bean id="abstractXADataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close" abstract="true">  
       <property name="xaDataSourceClassName" value="${jdbc.xaDataSourceClassName}"/>  <!-- SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase, Hana]  -->
       <property name="poolSize" value="10" />  
       <property name="minPoolSize" value="10"/>  
       <property name="maxPoolSize" value="30"/>  
       <property name="borrowConnectionTimeout" value="60"/>  
       <property name="reapTimeout" value="20"/>  
       <property name="maxIdleTime" value="60"/>  
       <property name="maintenanceInterval" value="60"/>  
       <property name="loginTimeout" value="60"/>  
       <property name="testQuery" value="${validationQuery}"/>  
   	</bean>  
 	<bean id="masterDataSource" parent="abstractXADataSource">  
 		<property name="uniqueResourceName" value="masterDB" />  
	    <property name="xaProperties">
            <props>
           		<prop key="driverClassName">${jdbc.driverClassName}</prop>
                <prop key="url">${master.jdbc.url}</prop>
                <prop key="password">${jdbc.password}</prop>
                 <!--  <prop key="user">${jdbc.username}</prop> --> <!-- mysql -->
                <prop key="username">${jdbc.username}</prop>   <!-- durid -->
             	<prop key="initialSize">0</prop>
				<prop key="maxActive">20</prop> <!-- 若不配置则代码执行"{dataSource-1} inited"此处停止  -->
				<prop key="minIdle">0</prop>
				<prop key="maxWait">60000</prop>
           		<prop key="validationQuery">${validationQuery}</prop>
				<prop key="testOnBorrow">false</prop>
				<prop key="testOnReturn">false</prop>
				<prop key="testWhileIdle">true</prop>
				<prop key="removeAbandoned">true</prop>
				<prop key="removeAbandonedTimeout">1800</prop>
				<prop key="logAbandoned">true</prop>
				<prop key="filters">mergeStat</prop>
            </props>
        </property>
    </bean>  
   	<bean id="slaveDataSource" parent="abstractXADataSource">  
   		<property name="uniqueResourceName" value="slaveDB" />  
	    <property name="xaProperties">
            <props>
          		<prop key="driverClassName">${jdbc.driverClassName}</prop>
                <prop key="url">${slave.jdbc.url}</prop>
                <prop key="password">${jdbc.password}</prop>
                <!--  <prop key="user">${jdbc.username}</prop> -->
                <prop key="username">${jdbc.username}</prop>
               	<prop key="initialSize">0</prop>
				<prop key="maxActive">20</prop>
				<prop key="minIdle">0</prop>
				<prop key="maxWait">60000</prop>
                <prop key="validationQuery">${validationQuery}</prop>
				<prop key="testOnBorrow">false</prop>
				<prop key="testOnReturn">false</prop>
				<prop key="testWhileIdle">true</prop>
				<prop key="removeAbandoned">true</prop>
				<prop key="removeAbandonedTimeout">1800</prop>
				<prop key="logAbandoned">true</prop>
				<prop key="filters">mergeStat</prop>
            </props>
        </property>
    </bean>  
</beans>
2:spring主配置文件spring-context.xml:

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    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">  
                        
	<!-- 使用annotation 自动注册bean,并检查@Required,@Autowired的属性已被注入 -->
	<context:component-scan base-package="com.tx" />
	
 	<!-- 使用AspectJ方式配置AOP -->  
	<aop:aspectj-autoproxy />
	
	<!-- 引入属性配置文件 -->
 	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
		<property name="location" value="classpath:properties/database.properties" />        
	</bean>  
	
	<!--或 <context:property-placeholder location="classpath*:*.properties" /> -->
</beans> 
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=password
4:mybatis的配置mybatis-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	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">
	<description>MyBatis的数据库持久层配置/配置主-从数据源</description>
	<bean id="masterSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="configLocation" value="classpath:mybatis/mybatis-config-master.xml" />
        <property name="dataSource" ref="masterDataSource" />
    </bean>
 
    <bean id="slaveSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="configLocation" value="classpath:mybatis/mybatis-config-slave.xml" />
        <property name="dataSource" ref="slaveDataSource" />
    </bean>
</beans>
配置mybatis-config(此代码,只为测试分布式事务,并不涉及真实的业务!!!):

mybatis-config-master.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias alias="Member"  type="com.tx.entity.Member"/>
    </typeAliases>
    <mappers>
        <mapper resource="com/tx/xml/MemberMapper.xml" />
    </mappers>
</configuration>
mybatis-config-slave.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias alias="MemberInfo"  type="com.tx.entity.MemberInfo"/>
    </typeAliases>
    <mappers>
        <mapper resource="com/tx/xml/MemberInfoMapper.xml" />
    </mappers>
</configuration>
5:Mapper的管理及注入,为mybatis的dao层mapper接口注入[绑定]sqlSessionFactory:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	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">
	<description>MyBatis为不同的mapper注入sqlSessionFactory</description>
    <!-- Mapper的管理及注入 -->
    <bean id="memberMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="sqlSessionFactory" ref="masterSqlSessionFactory" />
        <property name="mapperInterface" value="com.tx.dao.MemberMapper" />
    </bean>
     
    <bean id="memberInfoMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="sqlSessionFactory" ref="slaveSqlSessionFactory" />
        <property name="mapperInterface" value="com.tx.dao.MemberInfoMapper" />
    </bean>
</beans>
6:atomikos事务配置transaction-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	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">
	<description>配置事物</description>
	<!-- atomikos事务管理器 -->
	<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">
        <property name="forceShutdown">
            <value>true</value>
        </property>
    </bean>
 
    <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
        <property name="transactionTimeout" value="300" />
    </bean>
 	<!-- spring 事务管理器 -->  
    <bean id="springTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManager" ref="atomikosTransactionManager" />
        <property name="userTransaction" ref="atomikosUserTransaction" />
        <!-- 必须设置,否则程序出现异常 JtaTransactionManager does not support custom isolation levels by default -->
        <property name="allowCustomIsolationLevels" value="true"/> 
    </bean>

    <aop:config  proxy-target-class="true">
        <aop:advisor pointcut="(execution(* com.tx.service.*.* (..)))" advice-ref="txAdvice" />
    </aop:config>
 
    <tx:advice id="txAdvice" transaction-manager="springTransactionManager">
        <tx:attributes>
            <tx:method name="get*"  propagation="REQUIRED"  read-only="true" />
            <tx:method name="find*"  propagation="REQUIRED"  read-only="true" />
            <tx:method name="has*"  propagation="REQUIRED"  read-only="true" />
            <tx:method name="locate*"  propagation="REQUIRED"  read-only="true" />
            <tx:method name="register*" propagation="REQUIRED" rollback-for="java.lang.Exception" />
        </tx:attributes>
    </tx:advice>
</beans>
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=DEBUG
8:代码(部分不涉及代码已删除):

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);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.tx.dao.MemberMapper" >
  <resultMap id="BaseResultMap" type="com.tx.entity.Member" >
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="username" property="username" jdbcType="VARCHAR" />
    <result column="password" property="password" jdbcType="VARCHAR" />
    <result column="status" property="status" jdbcType="TINYINT" />
  </resultMap>
  <sql id="Base_Column_List" >
    id, username, password, status
  </sql>
  <insert id="insert" parameterType="com.tx.entity.Member" >
    insert into member (id, username, password, 
      status)
    values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 
      #{status,jdbcType=TINYINT})
  </insert>
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.tx.dao.MemberInfoMapper" >
  <resultMap id="BaseResultMap" type="com.tx.entity.MemberInfo" >
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="nickname" property="nickname" jdbcType="VARCHAR" />
    <result column="realname" property="realname" jdbcType="VARCHAR" />
    <result column="age" property="age" jdbcType="TINYINT" />
  </resultMap>
  <sql id="Base_Column_List" >
    id, nickname, realname, age
  </sql>
  <insert id="insert" parameterType="com.tx.entity.MemberInfo" >
    insert into member_info (id, nickname, realname, 
      age)
    values (#{id,jdbcType=INTEGER}, #{nickname,jdbcType=VARCHAR}, #{realname,jdbcType=VARCHAR}, 
      #{age,jdbcType=TINYINT})
  </insert>
</mapper>
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.cnblogs.com/wangyong/p/4174326.html
Atomikos 中文说明文档:http://blog.csdn.net/sun8288/article/details/8674016

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

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3月前
|
资源调度 Java 调度
Spring Cloud Alibaba 集成分布式定时任务调度功能
定时任务在企业应用中至关重要,常用于异步数据处理、自动化运维等场景。在单体应用中,利用Java的`java.util.Timer`或Spring的`@Scheduled`即可轻松实现。然而,进入微服务架构后,任务可能因多节点并发执行而重复。Spring Cloud Alibaba为此发布了Scheduling模块,提供轻量级、高可用的分布式定时任务解决方案,支持防重复执行、分片运行等功能,并可通过`spring-cloud-starter-alibaba-schedulerx`快速集成。用户可选择基于阿里云SchedulerX托管服务或采用本地开源方案(如ShedLock)
129 1
|
1月前
|
前端开发 Java 应用服务中间件
【Spring】Spring MVC的项目准备和连接建立
【Spring】Spring MVC的项目准备和连接建立
57 2
|
2月前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
1月前
|
XML 前端开发 Java
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
本文阐述了Spring、Spring Boot和Spring MVC的关系与区别,指出Spring是一个轻量级、一站式、模块化的应用程序开发框架,Spring MVC是Spring的一个子框架,专注于Web应用和网络接口开发,而Spring Boot则是对Spring的封装,用于简化Spring应用的开发。
134 0
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
|
2月前
|
消息中间件 Java 对象存储
数据一致性挑战:Spring Cloud与Netflix OSS下的分布式事务管理
数据一致性挑战:Spring Cloud与Netflix OSS下的分布式事务管理
53 2
|
3月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
4月前
|
资源调度 Java 调度
Spring Cloud Alibaba 集成分布式定时任务调度功能
Spring Cloud Alibaba 发布了 Scheduling 任务调度模块 [#3732]提供了一套开源、轻量级、高可用的定时任务解决方案,帮助您快速开发微服务体系下的分布式定时任务。
14978 29
|
3月前
|
Java 微服务 Spring
SpringBoot+Vue+Spring Cloud Alibaba 实现大型电商系统【分布式微服务实现】
文章介绍了如何利用Spring Cloud Alibaba快速构建大型电商系统的分布式微服务,包括服务限流降级等主要功能的实现,并通过注解和配置简化了Spring Cloud应用的接入和搭建过程。
SpringBoot+Vue+Spring Cloud Alibaba 实现大型电商系统【分布式微服务实现】
|
3月前
|
SQL Java 数据库
10、MyBatis-Plus 多数据源
这篇文章介绍了在MyBatis-Plus中实现多数据源的方法,包括创建不同的数据库和表、引入动态数据源依赖、配置多个数据源、创建用户和商品的Service类,以及如何进行测试来验证多数据源的功能。
|
3月前
|
Dubbo Java 调度
揭秘!Spring Cloud Alibaba的超级力量——如何轻松驾驭分布式定时任务调度?
【8月更文挑战第20天】在现代微服务架构中,Spring Cloud Alibaba通过集成分布式定时任务调度功能解决了一致性和可靠性挑战。它利用TimerX实现任务的分布式编排与调度,并通过`@SchedulerLock`确保任务不被重复执行。示例代码展示了如何配置定时任务及其分布式锁,以实现每5秒仅由一个节点执行任务,适合构建高可用的微服务系统。
70 0

热门文章

最新文章

下一篇
无影云桌面