atomikos JTA 分布式事务配置和原理

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zwkwd/article/details/22683051

          概述

          本人现在正在做税务项目平台,为以后税务开发做准备,由于功能比较多,考虑到以后会有多种数据库参与,所以需要支持分布式事务.

对于事务,可以理解为原子操作,即要不都成功,要不都成仁.

         对于单个数据库来说,可以通过conn来对事务进行设置自己提交,来控制同一个conn下的事务处理,但是对于多数据库,或者是对于业务逻辑的原理处理,我们就需要用到分布式事务了,很常见的是跨行转账,可能要从农行数据库-100,加到建行数据+100,而且还必须同步.这在数据库级别的事务是没法处理的.

          原理

         Java 事务编程接口(JTA:Java Transaction API)和 Java 事务服务 (JTS;Java Transaction Service) 为 J2EE 平台提供了分布式事务服务。分布式事务(Distributed Transaction)包括事务管理器(Transaction Manager)和一个或多个支持 XA 协议的资源管理器 ( Resource Manager )。我们可以将资源管理器看做任意类型的持久化数据存储;事务管理器承担着所有事务参与单元的协调与控制。JTA 事务有效的屏蔽了底层事务资源,使应用可以以透明的方式参入到事务处理中;但是与本地事务相比,XA 协议的系统开销大,在系统开发过程中应慎重考虑是否确实需要分布式事务。若确实需要分布式事务以协调多个事务资源,则应实现和配置所支持 XA 协议的事务资源,如 JMS、JDBC 数据库连接池等.详情可以参照.

        atomikos 是实现了XA的一种分布式事务处理工具.平台使用spring + mybatis + atomikos.

首先applicationContext.xml 配置如下

	<!-- transaction manager all set-ups, use JtaTransactionManager for global 
		tx implemented by atomikosTransactionManager -->
	<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 bean="atomikosTransactionManager" />
		</property>
		<property name="userTransaction">
			<ref bean="atomikosUserTransaction" />
		</property>
	</bean>


	<!-- transaction declare method 1 : annotation -->
	<tx:annotation-driven transaction-manager="transactionManager" />

这里都是固定配置,transactionManager为事务调用接口.

接着看调用

	//事务测试
	@RequestMapping("/apexResource.test.do")
	@ResponseBody
	//@Transactional(rollbackFor=Exception.class)
	@LogAnnotation(eventCode="APEX_CTR_002",eventProcess="当前节点下所有子节点数据")
	public String testxa(ModelMap map) throws Exception{
		String json = null;
		String value = this.getTrimParameter("aa");
		String value2 = this.getTrimParameter("bb");
		String bug = this.getTrimParameter("bug");
			transactionManager.getUserTransaction().begin();
			ApexRank a = new ApexRank();
			a.setSysGuid(value);
			a.setRankName(value);
			
			apexRankService.doInsert(a);
			ApexRole b = new ApexRole();
			b.setSysGuid(value2);
			b.setRoleName(value2);
			bug.equals("");
			apexRoleService.doInsert(b);
			transactionManager.getUserTransaction().commit();
		
		return "11";
	}

其中bug为null 所以 equal会报错,事务成功回滚,

	@Resource
	private IApexRoleService apexRoleService;
	@Resource
	private IApexPositionService apexPostionService;
	
	@Resource
	private IApexRankService apexRankService;

        @Resource 
	JtaTransactionManager transactionManager;

 apexRoleService 和 apexRankService 为两个数据源,

当然如果直接使用@Transactional(rollbackFor=Exception.class) 也可以,不过要注意在掉片段是不要用try-catch,或者finally 返回,貌似注解在返回之后调用,应该新建一个service层,在里面加入事务处理即可



展开阅读全文

没有更多推荐了,返回首页