Spring3.0+Hibernate+Atomikos集成构建JTA的分布式事务--解决多数据源跨库事务
一、概念
分布式事务
分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。简言之,同时操作多个数据库保持事务的统一,达到跨库事务的效果。
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的分布式事务
二、Spring.x+Hibernate+Atomikos集成
Spring.x+Hibernate怎么集成此处省略不说,主要讲解Spring.x+Atomikos的集成,操作步骤如下:
1、下载Atomikos,需要以下这些包
atomikos-util-1.0.jar
cglib-nodep-2.2.2.jar
transactions-3.7.0.jar
transactions-api-3.7.0.jar
transactions-jdbc-3.7.0.jar
transactions-jta-3.7.0.jar
2、配置
在applicationContext.xml文件当中作如下配置
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<context:annotation-config /> <!-- 通过注解方式自动扫描需交给sping管理的Bean -->
<context:component-scan base-package="com.ljq" /> <!-- spring atomikos配置 -->
<!-- bpm数据源 -->
<bean id="bpmDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
init-method="init" destroy-method="close">
<!-- Set unique name for this DataSource -->
<property name="uniqueResourceName"><value>bpm</value></property>
<!-- Set XADatasource class name-->
<property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
<property name="xaProperties">
<props>
<prop key="user">root</prop>
<prop key="password">parami2013</prop>
<prop key="url">jdbc:mysql://192.168.1.254:3306/parami_bpm</prop>
</props>
</property>
<!-- 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> <!-- center数据源 -->
<bean id="centerDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
init-method="init" destroy-method="close">
<property name="uniqueResourceName"><value>center</value></property>
<property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
<property name="xaProperties">
<props>
<prop key="user">root</prop>
<prop key="password">parami2013</prop>
<prop key="url">jdbc:mysql://192.168.1.254:3306/parami_center</prop>
</props>
</property>
<!-- 连接池里面连接的个数 -->
<property name="poolSize" value="3" />
<!-- 管理 Connection 被占用的时间 -->
<!-- 如果不设置这个值,Atomikos使用默认的300秒(即5分钟),那么在处理大批量数据读取的时候,一旦超过5分钟,就会抛出类似 Resultset is close 的错误 -->
<property name="reapTimeout"><value>20000</value></property>
</bean> <!-- 将hibernate数据源注入sessionFactory -->
<bean id="bpmSessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="bpmDataSource" />
<property name="packagesToScan">
<list>
<value>com.ljq.pojo</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<!-- 慎重(推荐禁止) 固定为update -->
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop>
</props>
</property>
</bean> <!-- 将hibernate数据源注入sessionFactory -->
<bean id="centerSessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="centerDataSource" />
<property name="packagesToScan">
<list>
<value>com.ljq.pojo</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<!-- 慎重(推荐禁止) 固定为update -->
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop>
</props>
</property>
</bean> <!-- 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 事务管理器 -->
<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> <!-- 使用annotation定义事务,对于要加入事物的类,只需对该类加 @Transactional -->
<tx:annotation-driven transaction-manager="springTransactionManager" /> <!-- hibernate Dao层模板 -->
<bean id="bpmHibernateTemplate"
class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="bpmSessionFactory"></property>
</bean> <bean id="centerHibernateTemplate"
class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="centerSessionFactory"></property>
</bean> </beans>
3、在src文件夹下面加入一个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=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=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
4、注入HibernateTemplate模板
a、为bpm库注入HibernateTemplate模板
public abstract class BpmDaoSupport<T> extends DaoSupport<T> {
protected HibernateTemplate bpmHibernateTemplate; /**
* HibernateTemplate注入
*
* @param bpmHibernateTemplate
*/
@Resource
public void setBpmHibernateTemplate(HibernateTemplate bpmHibernateTemplate) {
this.bpmHibernateTemplate = bpmHibernateTemplate;
setHibernateTemplate(bpmHibernateTemplate);
} }
b、为center库注入HibernateTemplate模板
public abstract class CenterDaoSupport<T> extends DaoSupport<T> {
protected HibernateTemplate centerHibernateTemplate; /**
* HibernateTemplate注入
*
* @param centerHibernateTemplate
*/
@Resource
public void setCenterHibernateTemplate(HibernateTemplate centerHibernateTemplate) {
this.centerHibernateTemplate = centerHibernateTemplate;
setHibernateTemplate(centerHibernateTemplate);
}
}
5、编写业务逻辑代码
@Service(value="userServiceBean")
@Transactional
public class UserServiceBean implements UserService {
@Resource(name="userDaoBean") private UserDao userDao;
@Resource(name="userRoleDaoBean") private UserRoleDao userRoleDao; public List<User> queryUser() {
return userDao.queryUser();
} public void save(User user, UserRole ur) {
userDao.save(user); //a处
//此处报异常
System.out.println(1/0); //b处
ur.setUserId(user.getUid());
userRoleDao.save(ur); //c处
}
}
在执行save()方法时会报java.lang.ArithmeticException: / by zero异常,b处的“1/0”有问题,因为除数不能为0;
如果事务生效,save()方法会回滚掉,即a处、c处不做save操作,保持事务的原子性;
如果事务不起作用,那么a处会执行成功,往数据库添加一条记录;b处抛出异常终止向下执行;c处这条代码不执行,导致脏数据的出现。
Atomikos的集成到此就结束了,亲!是不是很简单。
注意
mysql的驱动需要5.1.10版本以上,低版本会出现如下错误:
java.lang.IllegalArgumentException: null source
Spring3.0+Hibernate+Atomikos集成构建JTA的分布式事务--解决多数据源跨库事务的更多相关文章
- spring3.0+Atomikos 构建jta的分布式事务 -- NO
摘自: http://gongjiayun.iteye.com/blog/1570111 spring3.0+Atomikos 构建jta的分布式事务 spring3.0已经不再支持jtom了,不过我 ...
- spring3.0+Atomikos 构建jta的分布式事务
摘自: http://gongjiayun.iteye.com/blog/1570111 spring3.0+Atomikos 构建jta的分布式事务 spring3.0已经不再支持jtom了,不过我 ...
- 使用spring+hibernate+atomikos+tomcat构建分布式事务
本文通过一个demo,介绍如何使用spring+hibernate+atomikos+tomcat构建在一个事务中涉及两个数据源的web应用. demo功能:实现一个能成功提交和回滚的涉及两个数据库数 ...
- java跨库事务Atomikos
1:引入额外的jar <dependency> <groupId>com.atomikos</groupId> <artifactId>transact ...
- Spring 3.0 + Atomikos构建jta分布式事务
Spring3.0已经不再支持jtom了,不过我们可以用第三方开源软件atomikos(http://www.atomikos.com/)来实现.Atomikos是目前在分布式事务管理中做得相当不错的 ...
- 模块化之Spring3.0 web fragment和gradle构建项目
1.背景 模块化开发很久以前就开始普及的概念.但是到了企业实际情况中,真正把模块化作为系统架构的核心的不多.或者说对模块化有这个意识,但是具体到底该如何实现,有些模糊,同时也许因为项目紧.任务中. ...
- spring3.0的jar包详解
1. spring.jar 是包含有完整发布模块的单个jar 包. 2. org.springframework.aop 包含在应用中使用Spring的AOP特性时所需的类. 3. org.sprin ...
- Jbpm4.4+hibernate3.5.4+spring3.0.4+struts2.1.8整合例子(附完整的请假流程例子,jbpm基础,常见问题解决)
Jbpm4.4+hibernate3.5.4+spring3.0.4+struts2.1.8 整合例子(附完整的请假流程例子). 1.jbpm4.4 测试环境搭建 2.Jbpm4.4+hibernat ...
- 开发基础框架:mybatis-3.2.8 +hibernate4.0+spring3.0+struts2.3
一:项目下载地址(点击 Source code(zip)) https://github.com/fzxblgong/frame_2014-12-15/releases 版本:v1.2大小:20M 二 ...
随机推荐
- flask第七篇——URL与视图函数的映射
有兴趣的朋友可以添加微信公众号:自动化测试实战 今天开始就要进入正题了.大家都准备好了吧~ 代码提示 先和大家说个小知识点:有同学后台说输入flask代码pycharm不提示,现在告诉你一个解决方法: ...
- 【mongodb】Mongodb初识
MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系 ...
- Linux安装vsftpd总结
我使用的是CentOS6安装的vsftpd,转载请注明出处,以下是我的记录: #查看是否已经安装了vsfptd vsftpd -v #安装 yum -y install vsftpd #创建:chro ...
- spring注解实现业务层事务管理,当业务层自调用时,事务失效问题解决
前些日子一朋友在需要在目标对象中进行自我调用,且需要实施相应的事务定义,且网上的一种通过BeanPostProcessor的解决方案是存在问题的.因此专门写此篇帖子分析why. 1.预备知识 aop概 ...
- thinkphp 使每一个模板页都包括一个header文件和一个footer文件
在开发的过程中,常常遇到要使每一个模板页都包括一个header文件和一个footer文件.thinkPHP的模板布局为我们提供了一个叫全局配置方式可以解决问题. 1. 在配置文件里开启LAYOUT_O ...
- linux下如何添加一个用户并且让用户获得root权限【转载】
原文:http://www.cnblogs.com/johnw/p/5499442.html 1.添加用户,首先用adduser命令添加一个普通用户,命令如下: #adduser tommy //添加 ...
- ubuntu 12.04 下 Vim 插件 YouCompleteMe 的安装
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4137402.html 1.需要保证vim的版本大于7.3.584,否则的话需要更新vim 可 ...
- yum方式安装的Apache目录详解和配置说明
在对httpd.conf文件进行解读之前,首先了解一下Redhat9中Apache服务器默认配置的一些基本信息:配置文件:/etc/httpd/conf/http.conf1)"/etc/h ...
- 常见企业IT支撑【5、内网DNS cache轻量服务dnsmasq】
可参考http://www.centoscn.com/CentosServer/dns/2014/0113/2355.html 布署keepalive高可用方式 此方案只适合小型企业,规模少的情况下使 ...
- Ubuntu12.10下Python(cx_Oracle)访问Oracle解决方案
第一步:下载安装cx_Oracle 下载地址:http://sourceforge.net/projects/cx-oracle/files/5.1.2/,下载cx_Oracle的rmp安装文件,注意 ...