Atomikos实现分布式事物管理

  分布式事务管理,简单来说就是多个数据库之间的事务管理。之前也试过使用Spring动态切换数据库,通过继承AbstractRoutingDataSource重写determineCurrentLookupKey()方法,来决定使用那个数据库。在开启事务之前,通过改变lookupKey来达到切换数据源目的。但是这种方法多个数据库之前没办法做事务管理,或许对于主从(读写)数据库会好用一些,而对于需要一个操作中更新多个数据库的情况,使用Atomikos或许会更好一些。

  本文采用spring4+hibernate4+Atomikos进行事务管理。

  Atomikos要使用的库使用maven导入,spring和hibernate的依赖就不一一列出,需要额外添加的dependency如下:

    <dependency>
            <groupId>com.atomikos</groupId>
            <artifactId>atomikos-util</artifactId>
            <version>3.9.3</version>
        </dependency>
        <dependency>
            <groupId>com.atomikos</groupId>
            <artifactId>transactions-jdbc</artifactId>
            <version>3.9.3</version>
        </dependency>
        <dependency>
            <groupId>com.atomikos</groupId>
            <artifactId>transactions-jta</artifactId>
            <version>3.9.3</version>
        </dependency>
        <dependency>
            <groupId>com.atomikos</groupId>
            <artifactId>transactions</artifactId>
            <version>3.9.3</version>
        </dependency>
        <dependency>
            <groupId>com.atomikos</groupId>
            <artifactId>transactions-api</artifactId>
            <version>3.9.3</version>
        </dependency>
        <dependency>
            <groupId>javax.transaction</groupId>
            <artifactId>jta</artifactId>
            <version>1.1</version>
        </dependency>

  使用的数据库驱动依赖如下:

        <!-- 加入mysql驱动依赖包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>
        <!-- sql server数据库驱动 -->
        <dependency>
            <groupId>net.sourceforge.jtds</groupId>
            <artifactId>jtds</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!-- 加入druid数据源依赖包 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.26</version>
        </dependency>            

  有点需要注意的是,druid的版本应该跟上mysql的版本,不然可能找不到MySQL的XADataSource。

  配置数据源xml代码:

  <bean id="mysql" class="com.alibaba.druid.pool.xa.DruidXADataSource" init-method="init" destroy-method="close">
        <property name="url" value="${jdbc_url}" />
        <property name="username" value="${jdbc_username}" />
        <property name="password" value="${jdbc_password}" />

        <!-- 初始化连接大小 -->
        <property name="initialSize" value="0" />
        <!-- 连接池最大使用连接数量 -->
        <property name="maxActive" value="20" />
        <!-- 连接池最小空闲 -->
        <property name="minIdle" value="0" />
        <!-- 获取连接最大等待时间 -->
        <property name="maxWait" value="60000" />
        <!-- <property name="poolPreparedStatements" value="true" />
        <property name="maxPoolPreparedStatementPerConnectionSize" value="33" /> -->
        <property name="validationQuery" value="SELECT 1" />
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="false" />
        <property name="testWhileIdle" value="true" />
        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000" />
        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="25200000" />
        <!-- 打开removeAbandoned功能 -->
        <property name="removeAbandoned" value="true" />
        <!-- 1800秒,也就是30分钟 -->
        <property name="removeAbandonedTimeout" value="1800" />
        <!-- 关闭abanded连接时输出错误日志 -->
        <property name="logAbandoned" value="true" />

        <!-- 监控数据库 -->
        <!-- <property name="filters" value="mergeStat" /> -->
        <!-- <property name="filters" value="stat" /> -->
        <!--<property name="filters" value="config" />
          <property name="connectionProperties" value="config.decrypt=true" />-->
    </bean>

    <bean id="mysqlDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
          init-method="init" destroy-method="close">
        <!-- Set unique name for this DataSource -->
        <property name="uniqueResourceName">
            <value>mysql</value>
        </property>
        <!-- Set XADatasource class name-->
        <property name="xaDataSource" ref="mysql"/>
        <!-- set properties for datasource connection pool -->
        <property name="poolSize" value="3" />
        <!-- 管理 Connection 被占用的时间 -->
        <!-- 如果不设置这个值,Atomikos使用默认的300秒(即5分钟),那么在处理大批量数据读取的时候,一旦超过5分钟,就会抛出类似 Resultset is close 的错误 -->
        <property name="reapTimeout"><value>20000</value></property>
    </bean>

  配置SessionFactory的xml代码:

<bean id="noticesSessionFactory"
          class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="mysqlDataSource" />
        <property name="jtaTransactionManager" ref="springTransactionManager"></property>
        <property name="packagesToScan">
            <list>
                <value>com.test.model</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <!-- 慎重(推荐禁止) 固定为update -->
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.autoReconnect">true</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
                <prop key="hibernate.use_sql_comments">${hibernate.use_sql_comments}</prop>
                <prop key="hibernate.jdbc.batch_size">${hibernate.batch_size}</prop>
            </props>
        </property>
    </bean>

  如果要使用getCurrentSession()的话,要注意加上:

<property name="jtaTransactionManager" ref="springTransactionManager"></property>

  添加多个数据库的话,只需要把上面的xml再写一遍。

  下面配置atomikos的事务管理器xml代码:

<!-- 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的事务管理器xml代码:

<!-- spring 事务管理器 -->
    <bean id="springTransactionManager"
          class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManager" ref="atomikosTransactionManager"/>
        <property name="userTransaction" ref="atomikosUserTransaction" />
        <property name="allowCustomIsolationLevels" value="true"/>
    </bean>

    <!-- 注解方式配置事物-->
   <tx:annotation-driven transaction-manager="springTransactionManager" />

  添加transactions.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=false

# 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=WARN

# 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

  好了,Atomikos算是配置完成,我们可以写代码测试一下。测试的代码这里就不写出了。

  性能优化:尽管这个软件有着很大的优势,但是想要更好的发挥其作用,可以按以下的方法优化:

  l 更高的内存,意味着更高的吞吐量(每秒的事务数目)

  l 使连接池尽可能的大

  l 一旦你不需要的连接请马上关闭它们。不要把你的应用程序放在缓存里,让内部连接池为你做这些,这将促使更高效的连接使用

  l 不要让活动的事务闲置:终止所有情况下的事务,尤其是在异常报错情况下的事务。这将减少数据库的锁定时间,并且最大效率的处理启用的使用。

  这么长的配置文件要小心点写,我的粗心结果就是datasource乱套了,导致花了不少时间排错。当然还有各种乱七八糟的糟心问题,这些问题会在后面的文章中列出来,大家可以注意避免。最后用上Atomikos的分布式事务,没有了各种的脏数据,舒心了不少。

时间: 2024-10-27 05:22:36

Atomikos实现分布式事物管理的相关文章

Spring事务隔离级别与传播机制,spring+mybatis+atomikos实现分布式事务管理

本文转载于本人另一博客[http://blog.csdn.net/liaohaojian/article/details/68488150] 1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功.其必须遵循四个原则(ACID). 原子性(Atomicity):即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做: 一致性(Consistency):在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是应该处于正确

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

转载自:http://blog.csdn.net/liaohaojian/article/details/68488150 1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功.其必须遵循四个原则(ACID). 原子性(Atomicity):即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做: 一致性(Consistency):在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是应该处于正确的状态,即数据完整

使用springboot+jta+atomikos&#160;分布式事物管理

当项目在连接多个数据库时可能会发生事务问题,即一个库的事务不可能去操作另一个数据库的事务,这时就需要使用atomikos对数据库的事务进行统一的管理 第一步添加atomikos的依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency>

srping atomikos 的jta 事物管理

加入bean <dependency> <groupId>com.atomikos</groupId> <artifactId>transactions-jta</artifactId> <version>4.0.0M4</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifa

springboot(九):事物管理

SpringBoot整合事物管理 Springboot默认集成事物,只主要在方法上加上@Transactional即可. 多数据源情况下事物怎么管理事物 对于这种传统的分布式事物管理,采用jta+atomikos 分布式事物管理.Atomikos 是一个为Java平台提供增值服务的并且开源类事务管理器. 新增jta-atomikos依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifa

第十一章 SpringBoot事物管理器

一.springboot整合事物管理 springboot默认集成事物,只主要在方法上加上@Transactional即可 二.SpringBoot分布式事物管理 使用springboot+jta+atomikos 分布式事物管理 1.pom文件 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-parent</artifactId> <

spring 事物管理

1 在spring中支持编程式事物和声明式事务管理,通常使用声明式事物管理,声明式的事物管理是基于aop机制实现的使用很方便. 2 spring支持单一数据库资源的事物管理和跨越多个数据库资源的事物管理既JTA全局事物. 3 在spring中提供了多个事物管理类,常用的是;DataSourceTransactionManager,HibernateTransactionManager和JtaTransactionManager. DataSourceTransactionManager :数据源

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

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

spring+springMVC+Mybatis架构下采用AbstractRoutingDataSource、atomikos、JTA实现多数据源灵活切换以及分布式事务管理

背景: 1.系统采用SSM架构.需要在10多个MYSQL数据库之间进行切换并对数据进行操作,上篇博文<springMVC+Mybatis(使用AbstractRoutingDataSource实现多数据源切换时)事务管理未生效的解决办法> 2.第一步先通过AbstractRoutingDataSource实现了多数据源的灵活切换,但是后来发现事务不起作用: 3.发现问题是因为重复扫描service包导致第二次扫入容器的BEAN没有纳入事务管理,因此在springMVC的配置文件中排除了对Ser