一、概念
分布式事务
分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。简言之,同时操作多个数据库保持事务的统一,达到跨库事务的效果。
JTA
JTA,即Java Transaction API,JTA允许应用程序执行分布式事务处理———在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序的JTA支持极大地增强了数据访问能力。
JTA和JTS
Java事务API(JTA:Java Transaction API)和它的同胞Java事务服务(JTS:Java Transaction Service),为J2EE平台提供了分布式事务服务(distributed transaction)。
一个分布式事务(distributed transaction)包括一个事务管理器(transaction manager)和一个或多个资源管理器(resource manager)。
一个资源管理器(resource manager)是任意类型的持久化数据存储。
事务管理器(transaction manager)承担着所有事务参与单元者的相互通讯的责任。
JTA与JDBC
JTA事务比JDBC事务更强大。一个JTA事务可以有多个参与者,而一个JDBC事务则被限定在一个单一的数据库连接。下列任一个Java平台的组件都可以参与到一个JTA事务中:JDBC连接、JDO PersistenceManager 对象、JMS 队列、JMS 主题、企业JavaBeans(EJB)、一个用J2EE Connector Architecture 规范编译的资源分配器。
JOTM
JOTM (Java Open Transaction Manager)是一个开源独立的事务管理器,支持分布式事务,Spring3.X已经不再支持JOTM。
Atomikos
Atomikos TransactionsEssentials是一个为Java平台提供增值服务的并且开源类事务管理器,支持分布式事务,本文所采用的技术。
Atomikos是目前在分布式事务管理中做得相当不错的开源软件。有10年以上的经验,Atomikos保障您的关键事务和防止昂贵的数据丢失在发生系统故障或事故中.Atomikos支持XA(全局事务)和NON-XA(非全局事务),NON-XA效率高于XA。本文主要是讲XA事件,因为要在不同的数据库中操作多张表。
接下来说一下Spring.x+Hibernate中集成Atomikos构建JTA的分布式事务
二、准备
Atomikos TransactionsEssentials 是一个为Java平台提供增值服务的并且开源类事务管理器,官方地址:http://www.atomikos.com/,使用最新版本3.9.3,下载以下jar包:
atomikos-util-3.9.3.jar transactions-3.9.3.jar transactions-api-3.9.3.jar transactions-hibernate3-3.9.3.jar transactions-jdbc-3.9.3.jar transactions-jms-3.9.3.jar transactions-jta-3.9.3.jar |
官方地址经常打不开,需要国外vpn访问。可以通过maven地址进行下载。
SSH框架版本为,struts2的版本为2.3.20,spring的版本为3.0.6,Hibernate的版本为 3.6.8.Final
三、配置
3.1 spring的配置如下:
<!-- mysql数据源 --> <bean id="mysqlDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close"> <property name="uniqueResourceName" value="mysqlWebXADBMS" /> <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" /> <property name="xaProperties"> <props> <prop key="user">${jdbc.username.mysql}</prop> <prop key="password">${jdbc.password.mysql}</prop> <prop key="URL">${jdbc.url.mysql}</prop> <prop key="pinGlobalTxToPhysicalConnection">true</prop> <prop key="autoReconnect">true</prop> </props> </property> <property name="poolSize" value="${pool.initialPoolSize}" /> <property name="minPoolSize" value="${pool.minPoolSize}" /> <property name="maxPoolSize" value="${pool.maxPoolSize}" /> <property name="maxIdleTime" value="${pool.maxIdleTime}" /> <property name="testQuery" value="select 1" /> </bean> <!-- oracle数据源 --> <bean id="oracleDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close"> <property name="uniqueResourceName" value="oracleWebXADBMS" /> <property name="xaDataSourceClassName" value="oracle.jdbc.xa.client.OracleXADataSource" /> <property name="xaProperties"> <props> <prop key="user">${jdbc.username}</prop> <prop key="password">${jdbc.password}</prop> <prop key="URL">${jdbc.url}</prop> </props> </property> <property name="poolSize" value="${pool.initialPoolSize}" /> <property name="minPoolSize" value="${pool.minPoolSize}" /> <property name="maxPoolSize" value="${pool.maxPoolSize}" /> <property name="maxIdleTime" value="${pool.maxIdleTime}" /> <property name="testQuery" value="select 1 from dual" /> </bean> <!-- 对应的oracleSessionFactory配置(Hibernate的): --> <bean id="oracleSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <!---采用注解扫描实体 --> <property name="packagesToScan" value="org.gjwu.web.entity" /> <property name="dataSource" ref="oracleDataSource" /> <property name="namingStrategy"> <bean class="org.hibernate.cfg.ImprovedNamingStrategy" /> </property> <property name="jtaTransactionManager" ref="atomikosTransactionManager" /> <!--hibernate 配置属性,可以参考Hibernate帮助文档这里只罗列和jta相关的配置 --> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop> <prop key="hibernate.current_session_context_class">jta</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">false</prop> <prop key="hibernate.cache.use_query_cache">false</prop> <prop key="hibernate.cache.use_second_level_cache">false</prop> <prop key="hibernate.transaction.factory_class"> com.atomikos.icatch.jta.hibernate3.AtomikosJTATransactionFactory </prop> <prop key="hibernate.transcation.manager_lookup_class"> com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup </prop> <!-- <prop key="hibernate.connection.release_mode">after_statement</prop> --> </props> </property> </bean> <!-- 对应的mysqlSessionFactory配置(Hibernate的): --> <bean id="mysqlSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <!---采用注解扫描实体 --> <property name="packagesToScan" value="org.gjwu.web.mysql.entity" /> <property name="dataSource" ref="mysqlDataSource" /> <property name="namingStrategy"> <bean class="org.hibernate.cfg.ImprovedNamingStrategy" /> </property> <property name="jtaTransactionManager" ref="atomikosTransactionManager" /> <!--hibernate 配置属性,可以参考Hibernate帮助文档这里只罗列和jta相关的配置 --> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop> <prop key="hibernate.current_session_context_class">jta</prop> <prop key="hibernate.transaction.factory_class"> com.atomikos.icatch.jta.hibernate3.AtomikosJTATransactionFactory </prop> <prop key="hibernate.transcation.manager_lookup_class"> com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup </prop> <!-- <prop key="hibernate.connection.release_mode">after_statement</prop> --> </props> </property> </bean> <!-- 定义 oracleHibernateTemplate 用于注入到对应dao --> <bean id="oracleHibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="alwaysUseNewSession" value="false"></property> <property name="sessionFactory" ref="oracleSessionFactory"></property> </bean> <!-- 定义 mysqlHibernateTemplate 用于注入到对应dao --> <bean id="mysqlHibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="alwaysUseNewSession" value="false"></property> <property name="sessionFactory" ref="mysqlSessionFactory"></property> </bean> <!--进行jta的配置 --> <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="240" /> </bean> <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager" ref="atomikosTransactionManager" /> <property name="userTransaction" ref="atomikosUserTransaction" /> <property name="allowCustomIsolationLevels" value="true" /> </bean> <context:annotation-config /> <tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager" /> <context:component-scan base-package="org.gjwu.web" />
3.2 新增Atomikos配置文件:transactions.properties,放入到src目录下
# 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 # \uFF08also known as the 'console file'\uFF09\u3002 # # com.atomikos.icatch.console_file_name = tm.out # Size limit \uFF08in bytes\uFF09 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 = ${app.path.log} # Set directory of log files; make sure this directory exists! # com.atomikos.icatch.log_base_dir = ${app.path.log} # 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 \uFF08in milliseconds\uFF09 for local transactions # # com.atomikos.icatch.default_jta_timeout = 10000 # Set the max timeout \uFF08in milliseconds\uFF09 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=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=false # Should two-phase commit be done in \uFF08multi-\uFF09threaded 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
主要修改这四项:
com.atomikos.icatch.output_dir = ${app.path.log} com.atomikos.icatch.log_base_dir = ${app.path.log} com.atomikos.icatch.console_log_level=WARN com.atomikos.icatch.enable_logging=false |
3.3为dao层注入hibernateTemplate
即可使用
四、遇到的问题
4.1 启动的时候报没设置hibernateTemplate或者SessionFactory
原因:没有注入HibernateTemplate模板
4.2 启动成功后经常有以下异常:
com.atomikos.datasource.ResourceException: XA resource 'mysqlMessage2XADBMS': resume for XID '3231382E36382E3235302E3132302E746D32313734343030323732:3231382E36382E3235302E3132302E746D3533383839' raised -5: invalid arguments were given for the XA operation
这个mysql的XA的bug,需要在数据源中设置
<prop key="pinGlobalTxToPhysicalConnection">true</prop>
<prop key="autoReconnect">true</prop>
4.3 同一台机子或代码启动多个应用程序失败
需要在Atomikos的配置文件中transactions.properties
com.atomikos.icatch.enable_logging=false
进行禁用
相关推荐
本文将详细讲解"springboot-jpa atomikos 分布式事务管理"这一主题,以及如何在SpringBoot 2.0.5版本中结合JPA、Hibernate和MyBatis实现多数据库事务控制。 首先,SpringBoot是一个简化Spring应用开发的框架,它...
Spring Boot作为轻量级的Java开发框架,结合Atomikos这样的分布式事务管理器,可以有效地解决这些问题。本文将深入探讨如何在Spring Boot项目中实现Atomikos分布式事务以及动态数据源切换的两种示例。 首先,我们...
Atomikos 是一款开源的分布式事务处理库,它为Java应用程序提供了支持JTA(Java Transaction API)的事务管理服务。JTA是Java平台标准中定义的用于处理分布式事务的API,允许开发者在一个全局事务中处理多个数据库...
Atomikos通过实现JTA标准,提供了一种在Java应用程序中管理分布式事务的解决方案。 Spring框架是这个DEMO的核心部分,它是一个广泛应用的轻量级容器,提供了依赖注入、AOP(面向切面编程)等功能。在分布式事务处理...
Atomikos是一个开源的事务处理系统,专门设计用于在Java应用程序中实现分布式事务管理。它提供了JTA(Java Transaction API)的实现,使得开发者能够在不同的数据源之间进行复杂的事务操作,确保数据的一致性和完整...
Atomikos是一个强大的开源分布式事务处理框架,专为Java企业级应用设计,它提供了一种在分布式环境中确保数据一致性的方式。在大型系统中,尤其是在微服务架构或云环境下的复杂业务场景,分布式事务处理是必不可少的...
本项目"java+spring+mybatis+mysql+RuoYi-atomikos-实现分布式事务.zip"是一个基于若依(RuoYi)框架改造的多模块分布式事务解决方案,它利用了Atomikos这一强大的分布式事务管理器。以下将详细解析这个项目的知识点...
Atomikos是Java中的一款开源的事务管理器,尤其适用于处理JTA(Java Transaction API)级别的分布式事务。它能够使不同的数据源(如数据库、消息队列等)在同一事务中协同工作,确保数据的一致性。在Spring框架中,...
本教程将聚焦于如何利用Spring 3.0、Hibernate ORM框架以及Atomikos这个开源事务管理器来实现高效、可靠的多数据源分布式事务处理。 **Spring 3.0**: Spring是Java开发中最广泛使用的轻量级框架之一,它提供了一个...
Atomikos是一个强大的开源工具,专门用于处理分布式事务,尤其在Java企业级环境中(J2EE)发挥着关键作用。其4.0.4版本的jar包提供了全面的支持,以确保在多数据库环境中的数据一致性。以下是这些jar包的具体功能和...
Spring框架提供了强大的支持来处理分布式事务,而Atomikos是一个开源的事务管理器,专门用于处理JTA(Java Transaction API)事务,尤其适用于微服务和分布式环境。本教程将探讨如何结合Spring和Atomikos来实现...
SSH + atomikos 打造Java分布式事务 web工程 直接导入myeclipse即可运行 数据库可参照mutilDataSource/model下的实体类进行创建(两个表)数据库使用的是oracle
若依框架通过引入成熟的分布式事务解决方案,如Seata、Atomikos等,来解决这一问题。 3. **若依框架中的分布式事务配置** 在若依框架中,配置分布式事务通常涉及以下几个步骤: - 添加依赖:在项目的pom.xml或...
SSM(SpringMVC、Spring、MyBatis)框架是Java Web开发中常见的技术栈,而Atomikos则是一个强大的开源事务管理器,主要用于处理分布式事务。本案例以非Maven方式构建,展示了如何在不依赖Maven构建系统的情况下,...
本示例"spring+atomikos+druid分布式事务Demo"聚焦于如何在Spring框架中利用Atomikos和Druid来处理分布式事务。接下来,我们将深入探讨这三个组件以及它们在实现分布式事务中的作用。 Spring是一个广泛使用的Java...
本示例“spring mybatis atomikos 多库分布式事务demo”聚焦于如何在Spring与MyBatis框架下利用Atomikos实现跨数据库的分布式事务管理。 首先,Spring是一个广泛应用的开源框架,提供了丰富的功能,包括依赖注入、...
在这个案例中,我们将深入探讨如何使用Spring 4与Atomikos来实现跨数据库的分布式事务管理。 Atomikos是一款开源的事务处理监控器(Transaction Processing Monitor,TPM),它支持JTA(Java Transaction API)标准...
本教程将聚焦于如何在若依单体项目中集成Atomikos来实现分布式事务管理。 若依是一个基于Spring Boot的轻量级企业级快速开发平台,适用于构建各种规模的企业级应用。在单体项目中,当业务逻辑涉及多个数据库或服务...
Spring框架提供了多种实现分布式事务管理的方式,其中一种是通过集成第三方工具如Atomikos来实现。Atomikos是一个开源的事务处理服务,支持JTA(Java Transaction API),能很好地处理分布式环境中的ACID(原子性、...
Spring 框架提供了强大的事务管理能力,而JTA(Java Transaction API)是Java平台上的标准分布式事务处理接口。Atomikos 是一个开源的JTA实现,它为Spring提供了一个轻量级、高性能的分布式事务解决方案。本文将深入...