spring +hibernate+jotm整合多数据库事务控制

本文介绍如何在Spring框架中配置JTA事务管理,通过整合JOTM实现跨数据库的统一事务控制。具体步骤包括引入依赖包、配置JOTM参数、设置数据源及事务管理器等。

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

假如业务中要用到多个数据库,我们希望在业务方法中,当对某一个数据库的数据表进行操作的事务失败并回退(rollback),另外某一个数据库的数据表的操作事务也要回退,但应用一般的事务管理达不到这样的事务管理效果,这就需要实现 JTA 事务管理了。
这里我们在SPring中集成 Object web 的一个开源JTA实现JOTM (可以在http://jotm.objectweb.org下载完整版) 来实现JTA事务管理。

1、将必须的类包放入类路径中:
 jotm.jar, xapool.jar, jotm_jrmp_stubs.jar, jta-spect1_0_1.jar, connector-1_5.jar等等。

2、编写JOTM配置文件carol.properties,将其放到类路径下:
Java代码
#JNDI调用协议 
carol.protocols=jrmp 
#不使用CAROL JNDI封装器 
carol.start.jndi=false 
#不启动命名服务器 
carol.start.ns=false 

 

spring为JOTM提供了一个org.springframework.transaction.jta.JotmFactoryBean 支持类,可以用其方便地创建本地JOTM实例。

<?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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd 
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd 
	http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

	<bean id="mysqldatasource" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource">
		<property name="dataSource"><!--内部XA数据源
			--><bean class="org.enhydra.jdbc.standard.StandardXADataSource"
				destroy-method="shutdown">
				<property name="transactionManager" ref="jotm" />
				<property name="driverName" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/mdg" />
			</bean>
		</property>
		<property name="user" value="root" />
		<property name="password" value="8324759" />
	</bean>


	<bean id="h2datasource" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource">
		<property name="dataSource"><!--内部XA数据源
			--><bean class="org.enhydra.jdbc.standard.StandardXADataSource"
				destroy-method="shutdown">
				<property name="transactionManager" ref="jotm" />
				<property name="driverName" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/test" />
			</bean>
		</property>
		<property name="user" value="root" />
		<property name="password" value="8324759" />
	</bean>




	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		
			<!--<property name="configLocation" value="classpath:hibernate.cfg.xml">
		</property>
		--><property name="dataSource" ref="mysqldatasource">
		</property>

		<property name="mappingResources">
			<list>
				<value>com/ky/ssh/model/Admin.hbm.xml</value>
			</list>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.jdbc.batch_size">50</prop>
				<prop key="hibernate.cache.use_query_cache">true</prop>
				<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
			</props>
		</property>
		<property name="jtaTransactionManager">
			<ref bean="jotm" />
		</property>
	</bean>

	<bean id="sessionFactory2"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<!--<property name="configLocation" value="classpath:hibernate3.cfg.xml">
		</property>
	
			--><property name="dataSource" ref="h2datasource">
				</property>
	
			<property name="mappingResources">
				<list>
					<value>com/ky/ssh/database/User.hbm.xml</value>
				</list>
			</property>
			<property name="hibernateProperties">
				<props>
					<prop key="hibernate.dialect">org.hibernate.dialect.MYSQLDialect</prop>
					<prop key="hibernate.show_sql">true</prop>
					<prop key="hibernate.jdbc.batch_size">50</prop>
					<prop key="hibernate.cache.use_query_cache">true</prop>
					<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
				</props>
			</property>
			<property name="jtaTransactionManager">
				<ref bean="jotm" />
			</property>
			
	</bean>

	<bean id="adminDAO" class="com.ky.ssh.dao.AdminDAO">
		<property name="sessionFactory">
			<ref bean="sessionFactory" />
		</property>
	</bean>

	<bean id="userDAO" class="com.ky.ssh.dao.UserDAO">
		<property name="sessionFactory">
			<ref bean="sessionFactory2" />
		</property>
	</bean>

	<bean id="service" class="com.ky.service.Service">
		<property name="ad" ref="adminDAO"></property>
		<property name="ud" ref="userDAO"></property>
	</bean>
	<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean" />
	<!-- jtatransactionmanager容器 -->
	<bean id="transactionManager"
		class="org.springframework.transaction.jta.JtaTransactionManager">
		<property name="userTransaction" ref="jotm" />
	</bean>
	<!--
	指定userTransaction属性引用JOTM本地实例  -->
	<!--

		定义事务管理器(声明式的事务) <bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory2" /> </bean>
	-->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="upd*" propagation="REQUIRED" />
			<tx:method name="del*" propagation="REQUIRED" />
			<tx:method name="*" propagation="read-only" />
		</tx:attributes>
	</tx:advice>

	<aop:config>
		<aop:pointcut id="interceptorPointCuts" expression="execution(* com.ky.service.*.*(..))" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts" />
	</aop:config>

	<bean id="login" class="com.ky.action.Login">
		<property name="service" ref="service"></property>
	</bean>


</beans>

 

 
测试:

@Test
 publicvoid Test{
  ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
  Service s=(Service) ac.getBean("service");
  s.addUserAndAdmin("ky","123");
 }

 

可以成功插入数据至量数据库,若某一点出问题,可回滚

至此配置成功
 

资源下载链接为: https://pan.quark.cn/s/abbae039bf2a 在计算机科学领域,编译原理是研究如何将编程语言转化为机器可执行代码的理论基础。其中,三地址代码(Three-Address Code,TAC)作为一种中间表示形式,在编译器设计中经常被使用,尤其是在生成目标代码的阶段。本文将深入探讨三地址代码的概念、生成器的工作原理及其在编译过程中的作用。 三地址代码是一种简单的低级抽象语法树(AST)表示,每条指令涉及三个操作数,通常包括两个源操作数和一个目的操作数。这种格式简化了代码优化和目标代码生成的复杂性。例如,一个简单的算术表达式“x = y + z”在三地址代码中可能表示为: 在这个例子中,“t1”是一个临时变量,存储了“y + z”的结果,然后这个结果被赋值给“x”。 生成三地址代码的过程通常发生在编译器的中间阶段,即语法分析之后,语义分析之前。这个阶段称为“代码生成”或“中间代码生成”。编译器通过词法分析器处理源代码,将其转化为标记流;接着,语法分析器根据上下文无关文法将标记流解析成抽象语法树。三地址代码生成器就是在这个阶段介入,它遍历AST,为每个节点生成对应的三地址指令。 在Turbo C3.0这样的编译器环境下,开发者可以实现自己的三地址代码生成器。虽然Turbo C3.0是一款较老的编译器,但其C语言编译器设计原理依然适用于现代编译器开发。开发过程中,我们需要考虑如下关键点: 符号表管理:符号表记录了程序中所有标识符的类型、作用域和关联地址,对于生成三地址代码至关重要,因为它提供了关于操作数的类型信息。 数据类型转换:编译器必须处理不同数据类型的运算,确保它们在三地址代码中正确表示。例如,整型与浮点型之间的转换需要特别处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值