ssh框架加入atomikos分布式事务管理

本文介绍如何使用Atomikos实现Java平台上的JTA分布式事务管理,涵盖配置步骤及常见问题解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概念

 

 

 

分布式事务
分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。简言之,同时操作多个数据库保持事务的统一,达到跨库事务的效果。

 

 

 

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

进行禁用

 

 

Atomikos TransactionsEssentials 是一个为Java平台提供增值服务的并且开源类事务管理器,以下是包括在这个开源版本中的一些功能: l 全面崩溃 / 重启恢复 l 兼容标准的SUN公司JTA API l 嵌套事务 l 为XA和非XA提供内置的JDBC适配器 注释:XA:XA协议由Tuxedo首先提出的,并交给X/Open组织,作为资源管理器(数据库)与事务管理器的接口标准。目前,Oracle、Informix、DB2和Sybase等各大数据库厂家都提供对XA的支持。XA协议采用两阶段提交方式来管理分布式事务。XA接口提供资源管理器与事务管理器之间进行通信的标准接口。XA协议包括两套函数,以xa_开头的及以ax_开头的。 以下的函数使事务管理器可以对资源管理器进行的操作: 1)xa_open,xa_close:建立和关闭与资源管理器的连接。 2)xa_start,xa_end:开始和结束一个本地事务。 3)xa_prepare,xa_commit,xa_rollback:预提交、提交和回滚一个本地事务。 4)xa_recover:回滚一个已进行预提交的事务。 5)ax_开头的函数使资源管理器可以动态地在事务管理器中进行注册,并可以对XID(TRANSACTION IDS)进行操作。 6)ax_reg,ax_unreg;允许一个资源管理器在一个TMS(TRANSACTION MANAGER SERVER)中动态注册或撤消注册。 l 内置的JMS适配器XA-capable JMS队列连接器 注释:JMS:jms即Java消息服务(Java Message Service)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。 l 通过XA API兼容第三方适配器 l 更好的整合您的项目 l 集成Hibernate 如何使用Atomikos TransactionsEssentials Atomikos TransactionsEssentials 是一个可靠的库,可以加入到您的Java应用程序,也就是说为了使用这个产品,您必须添加一些jar文件(包括在dist和lib文件夹下)到您的应用程序或者应用程序服务器。 请注意:Atomikos TransactionsEssentials是一个非常快速的嵌入式事务管理器,这就意味着,您不需要另外启动一个单独的事务管理器进程(不要查找任何的bin文件夹)。相反,您的应用服务器将有它自己的intra-VM事务管理器。 配置需求:至少Java1.5 jdk,并且最少128M的内存 性能优化:尽管这个软件有着很大的优势,但是想要更好的发挥其作用,可以按以下的方法优化: l 更高的内存,意味着更高的吞吐量(每秒的事务数目) l 使连接池尽可能的大 l 一旦你不需要的连接请马上关闭它们。不要把你的应用程序放在缓存里,让内部连接池为你做这些,这将促使更高效的连接使用 l 不要让活动的事务闲置:终止所有情况下的事务,尤其是在异常报错情况下的事务。这将减少数据库的锁定时间,并且最大效率的处理启用的使用。 如果想获取这些细节的更多信息,也要参阅文档说明部分。 值得注意的是,在我们所有的压力测试中,Atomikos TransactionsEssentials比J2EE的web容器更高效的吞吐量。这些测量值包括日志记录的高效的事务状态,同样,在我们所有的测量中,包括XA和non-XA,高效的效率是一样的。 在J2SE中使用Atomikos Transactions Essentials,只需要按以下步骤 将idst和lib中的jar包全部放入的项目中 创建或者自定义你应用的transactions.properties(或者jta.properties)文件(事务管理器的配置),然后将它放入到classpath中,安装文件夹中包涵一个实例文件;在properties文件中注释(#)后面的是默认值,取消一行并且改变默认值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值