Spring中对于事务的处理是使用Spring中非常重要的一项技术,Spring提供了一个统一的处理事务的模型它跨越JTA、JDBC、Hibernate、JPA等事务处理的API支持声明式的事务管理(我们最长听说的Spring的优点),同EJB中的声明式事务管理差不太多。这里啰嗦一下关于事务的管理Java中关于事务的处理概念有些多包括最基本的JDBC事务、Java的事务管理接口JTA、Hibernate也封装了自己的事务管理、包括本地事务和全局事务、Bean管理的事务和容器管理的事务(EJB重点CMT)、EJB有声明式的事务管理,这些概念有些事交叉和重叠的或者是以不同的角度进行的分类、关于java中事务的一下概念接触的多你可以就会有自己的体会,这里推荐一部本人认为还不错的一本书【Java事务设计策略】这本书相对简单可入门但要求你对各项技术有个大致的了解在看,个人认为只要你了解事务的本质这些技术都是为简化我们的编程。本文将主要介绍Spring的事务管理,其他内容请自行查找资料如果你愿意可以和笔者一起讨论,如果你认为本文有什么不正确的地方欢迎指出,可以通过网页下方的邮箱与本人联系。
1、Spring中事务的抽象
2、Spring的声明式事务管理
3、Spring可编程事务管理
1、Spring中事务的抽象
Spring为了统一各种事务处理抽象了一些基本的接口用来处理事务(当然你要对这些事务有个基本的了解),下面将介绍几个Spring最基本的接口来说明Spring对事务处理的抽象:
PlatformTransactionManager:这是Spring中关于事务最主要的接口,这是一个Service Provider Interface(SPI),你也可以使用它来处理编程处理事务,PlatformTransactionManager是一个接口他不会与JNDI资源紧密连接你可以通过Spring IoC容器轻松的获得PlatformTransactionManager的实现,Spring定义了一个TransactionException(继承java.lang.RuntimeException)异常来响应Spring中的事务异常,Developer可以选择处理这个异常但不是强制的,PlatformTransactionManager的任何方法都可以抛出未被捕获TransactionException异常。我们来看一下PlatformTransactionManager的定义:
public interface PlatformTransactionManager { TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; void commit(TransactionStatus status) throws TransactionException; void rollback(TransactionStatus status) throws TransactionException; }getTransaction(..):依赖TransactionDefinition参数返回一个TransactionStatus对象(下面介绍),TransactionStatus可以代表一个新的事务(1)或已经存在当前运行占中的一个已经存在的事务(2),(2)对于于J2EE事务上下文来说TransactionStatus与当前执行线程相关。
TransactionDefinition:这个接口中定义了一下关于事务的属性
isolation:事务隔离级别,默认为TransactionDefinition.ISOLATION_DEFAULT
propagation:事务传播特性,典型的是事务一个事务在一个Scope中执行,你也可以改变事务的行为当一个事务已经存在你可以挂起该事物新起一个事务执行执行完后在将前一个事务恢复执行,这是个嵌套在事务里的事务。Spring提供了类似于EJB总CMT的所有事务传播特性。
Timeout:事务超时设置
Read-only status:指定事务为只读事务
TransactionStatus:这是一个控制事务和查询事务状态的简单接口;
public interface TransactionStatus extends SavepointManager { boolean isNewTransaction(); boolean hasSavepoint(); void setRollbackOnly(); boolean isRollbackOnly(); void flush(); boolean isCompleted(); }
在Spring无聊你使用声明式事务管理还是编程管理事务定义一个PlatformTransactionManager是最基本的,PlatformTransactionManager的实现需要了解事务执行的环境像JDBC、JTA、Hibernate等,我们不需要去实现这个接口,Spring对各种环境都提供了一个相应的类来供开发者使用,你要做的就是确定你所使用的事务环境并在Spring中声明即可。下面将展示一个基本的JDBC事务;
声明JDBC DataSource:(这里使用的是dbcp,如果你使用的是proxool数据源或等其他数据源再这里修改即可)
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean>
将数据源和Spring的PlatformTransactionManager联系起来;
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>如果你使用的是Java EE容器中JTA你可以使用容器提供的DataSource,一般容器提供的DataSource同JNDI访问;
<?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:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd"> <jee:jndi-lookup id="dataSource" jndi-name="jdbc/testDataSource"/> <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager" /> </beans>如果你使用Hibernate提供的事务如下:1、提供SessionFactory实例;2、注册事务管理器
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan"> <list> <value>com.xyz.project</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> <prop key="hibernate.show_sql">false</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> </bean><bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean>
如果你使用Hibernate在JTA事务下修改一下注册的事务管理器;
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>在上述的情况下你的程序不许要做其他的任何改变,只是修改配置文件来配置是使用全局事务还是本地事务就可以了。
2、Spring的声明式事务管理(大多数情况下我们都会这样做)
Spring的声明式事务管理依赖Spring的AOP,Spring的声明式事务管理和EJB的CMT非常相似,你可以在方法级别上实现用户定义行为,必要的时候也可以调用setRollbackOnly(),下面是与EJB CMT的一下对比:
1)EJB CMT是与JTA事务紧密相关的,而Spring的声明式事务管理可以使用上面提到的任何事务环境。
2)你可以在Spring的任何类中使用
3)你可以声明事务回滚的规则,这个在编程管理事务和声明式事务管理中都可以使用
4)Spring中你可以通过AOP技术加入自定义行为,在EJB中你不能影响事务的行为除非设置了setRollbackOnly()
5)Spring不支持跨远程的事务上下文,如果以要这么做就使用EJB吧
。。。。。。。。。。