pring对事务管理提供完整的支持,包括:
提供一致的编程模型。
支持声明式事务管理。
支持简单的API来编程事务管理,而不用和类似JTA一样复杂的事务管理API打交道。
和Spring的抽象数据源较好地整合。
核心概念
Spring事务抽象的核心理念基于事务策略语义,事务策略通过 org.springframework.transaction.PlatformTransactionManager接口定义
java 代码
- 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可以表示一个新的或已经存在的事务。TransactionDefinition接口指定如下信息:
隔离级别
事务传播性,用来指定当一个事务方法执行在一个存在的事务上下文时,是继续运行在现有的上下文,还是创建一个新的事务。
指定事务超时
指定只读状态
TransactionStatus接口提供一些简单的方式用来控制事务执行和查询事务状态。
Spring提供几个缺省的事务管理器实现,包括DataSourceTransactionManager,HibernateTransactionManager和JtaTransactionManager,这些事务管理器适用于不同的应用场景。
资源同步
如何使用持久API,比如JDBC,JTA,HIBERNATE,正确处理资源的创建,清理以及通过PlatformTransactionManager触发事务同步呢?
最 好的办法是使用Spring提供的高层持久层API,这些API不是原生API的替换,而是在内部使用原生API处理资源创建,重用,清除,事务同步以及 异常映射,这样用户的数据访问代码不必关心这些底层细节。这些高层API都基于模板实现,比如JDBCTemplate, HibernateTemplate。
也 可以使用底层一点的类,比如DataSourceUtils,SessionFactoryUtils, PersistenceManagerFactoryUtils。如果应用程序需要直接处理原生API提供的资源类型,这些类提供获取容器管理的实例,事 务同步和异常映射的功能。
声明式事务管理
Spring2.0可以不再使用TransactionProxyFactoryBean来配置声明式事务。
EJB事务/Spring事务
EJB声明事务绑定到JTA,而Spring事务可以运行在任何环境。
Spring事务可以应用到任何类,而不是限制在EJB。
Spring提供声明式回滚规则,可以指定哪个异常将导致事务回滚,而EJB事务只能在发生系统异常时回滚事务。
Spring可以使用AOP提供自定义事务处理。
Spring不支持跨远程调用的事务传播,EJB提供这个特性,但是通常不应该让事务跨越远程调用。
Spring的声明式事务管理基于AOP代理,事务Advice是基于XML驱动的。Spring会基于事务配置元信息,合适的 PlatformTransactionManager和TransactionInterceptor生成一个AOP代理,驱动Around方式的事务 Advice。
配置Spring事务
下面的示例描述了一个典型的声明式事务设置,首先需要包含对http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd的引用,然后使用tx:advice定义事务Advice以及事务属性,最后使用aop:config定义advicor。
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:aop="http://www.springframework.org/schema/aop"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.Transaction management
- Spring Framework (2.0.2) 177
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
-
- <bean id="fooService" class="x.y.service.DefaultFooService"/>
-
- <tx:advice id="txAdvice" transaction-manager="txManager">
-
- <tx:attributes>
-
- <tx:method name="get*" read-only="true"/>
-
- <tx:method name="*"/>
- <!---->tx:attributes>
- <!---->tx:advice>
-
- <aop:config>
- <aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/>
- <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>
- <!---->aop:config>
- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
- <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
- <property name="url" value="jdbc:oracle:thin:@rj-t42:1521:elvis"/>
- <property name="username" value="scott"/>
- <property name="password" value="tiger"/>
- <!---->bean>
-
- <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="dataSource"/>
- <!---->bean>
-
- <!---->beans>
定义回滚规则
Spring缺省在发生unchecked异常的时候回滚 事务,也提供支持,可以自定义在抛出特定异常时回滚事务,下面示例配置在捕获NoProductInStockException时回滚事务。
xml 代码
- <tx:advice id="txAdvice" transaction-manager="txManager">
- <tx:attributes>
- <tx:method name="get*" read-only="false" rollback-for="NoProductInStockException"/>
- <tx:method name="*"/>
- tx:attributes>
- tx:advice>
也可以使用编程的方式回滚事务,示例代码如下:
java 代码
- public void resolvePosition() {
- try {
-
- } catch (NoProductInStockException ex) {
-
- TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
- }
- }
Tx:advice设置
Propagation……事务传播,缺省值为Required。
Isolation……隔离级别,缺省值为Default。
rollback-for……指定捕获哪些异常时需要回滚事务
no-rollback-for……指定捕获哪些异常时不需要回滚事务
timeout……指定事务超时,缺省为-1。
read-only……指定事务是否是只读的,缺省为false
@Transaction注记
Spring支持使用注记声明事务语义,前提是必须使用JDK 5。要使用事务注记,只需要添加合适的注记到类或者方法上,然后在上下文中添加如下配置即可:
xml 代码
- <tx:annotation-driven transaction-manager="txManager"/>
需要注意的是,@Transaction注记可以标注在接 口,类和方法上,但是推荐使用在具体类上,因为注记是不能继承的,如果Spring使用基于类的代理(CGLIB),事务声明将不会生效。
编程事务管理
有两种方式通过编程实现事务管理
使用TransactionTemplate类
直接使用PlatformTransactionManager类。