Spring支持的事务策略

JavaEE应用的传统事务有两种策略:全局事务和局部事务。

全局事务由应用服务器管理,需要底层服务器的JTA支持。

局部事务和底层所采用的持久化技术有关,当采用JDBC持久化技术时,需要使用Connection对象来操作事务;而采用Hibernate持久化技术时,需要使用Session对象来操作事务。

当采用传统的事务编程策略时,程序代码必然和具体的事务操作代码耦合,这样造成的后果是:当应用需要在不同的事务策略之间切换时,开发者必须手动修改程序代码。当使用Spring事务策略后,就可以改变这种状况。

Spring事务策略是通过PlatformTransactionManager接口实现的,该接口是Spring事务策略的核心。该接口的源代码如下:

public interface PlatformTransactionManager {
   //平台无关的获得事务的方法
   TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
   //平台无关的事务提交方法
   void commit(TransactionStatus status) throws TransactionException;
   //平台无关的事务回滚方法
   void rollback(TransactionStatus status) throws TransactionException;
}

PlatformTransactionManager是一个与任何事务策略分离的接口,随着底层不同事务策略的切换,应用必须采用不同的实现类。PlatformTransactionManager接口没有与任何事务资源捆绑在一起,它可以适应于任何的事务策略,结合Spring的IOC容器,可以向PlatformTransactionManager注入相关的平台特性。

PlatformTransactionManager接口有许多不同的实现类,应用程序面向于平台无关的接口编程,当底层采用不同的持久层技术时,系统只需使用不同的

PlatformTransactionManager实现类即可。而这种切换通常由Spring容器负责管理,应用程序既无须与具体的事务API耦合,也无须与特定实现类耦合,从而将应用和持久化技术、事务API彻底分离开来。

TransactionStatus对象表示一个事务。getTransaction(TransactionDefinition definition)返回的TransactionStatus对象,可能是一个新的事务,也可能是一个已经存在的事务对象;否则,系统将新建一个事务对象后返回。

TransactionDefinition接口定义了一个事务规则,该接口必须指定如下几个属性:

属性说明
事务隔离当前事务和其他事务的隔离程度。例如这个事务能否看到其他事务未提交的数据等。
事务传播通常,在事务中执行的代码都会在当前事务中运行。但是如果一个事务上下文已经存在,有几个选项可指定该事务性方法的执行行为。例如,大多数情况下,简单地在现有的事务上下文中运行;或者挂起现有事务,创建一个新的事务。Spring提供EJB CMT中所有的事务传播选项。
事务超时事务在超时前能运行多久,也就是事务的最长持续时间。如果事务一直没有被提交或回滚,将在超出该时间后,系统自动回滚事务。
只读状态只读事务不修改任何数据。在某些情况下,例如使用Hibernate时,只读事务是非常有用的优化。
TransactionStatus代表事务本身,它提供了简单的控制事务执行和查询事务状态的方法,这些方法在所有的事务API中都是相同的:

public interface TransactionStatus extends SavepointManager {
	boolean isNewTransaction();
	boolean hasSavepoint();
	void setRollbackOnly();
	boolean isRollbackOnly();
	boolean isCompleted();
}
public interface SavepointManager {
	Object createSavepoint() throws TransactionException;
	void rollbackToSavepoint(Object savepoint) throws TransactionException;
	void releaseSavepoint(Object savepoint) throws TransactionException;
}
Spring具体的事务管理由PlatformTransactionManager的不同实现类来完成。在Spring容器中配置PlatformTransactionManager Bean时,必须针对不同环境提供不同的实现类。

譬如针对 JDBC数据源 的局部事务策略的配置文件如下:

<?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:tx="http://www.springframework.org/schema/tx"
        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/tx 
                http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
    
    <!-- 定义数据源Bean,使用C3P0数据源实现 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
        <property name="user" value="scott"/>
        <property name="password" value="tiger"/>
        <property name="maxPoolSize" value="40"/>
        <property name="minPoolSize" value="1"/>
        <property name="initialPoolSize" value="1"/>
        <property name="maxIdleTime" value="20"/>
    </bean>
 
    <!-- 配置JDBC数据源的局部事务管理器,使用DataSourceTransactionManager类 -->
    <!-- 该类实现PlatformTransactionManager接口,是针对采用数据源连接的特定实现 -->
    <bean id="transactionManager" 
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
 </beans>

针对 Hibernate 的局部事务策略的配置文件如下:

<?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:tx="http://www.springframework.org/schema/tx"
        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/tx 
                http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
    
    <!-- 定义数据源Bean,使用C3P0数据源实现 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
        <property name="user" value="scott"/>
        <property name="password" value="tiger"/>
        <property name="maxPoolSize" value="40"/>
        <property name="minPoolSize" value="1"/>
        <property name="initialPoolSize" value="1"/>
        <property name="maxIdleTime" value="20"/>
    </bean>
    
    <!-- 定义Hibernate的SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mappingResources">
            <list>
                <value>lee/Xxx.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>
    
    <!-- 配置Hibernate的局部事务管理器,使用HibernateTransactionManager类 -->
    <!-- 该类实现PlatformTransactionManager接口,是针对采用Hibernate的特定实现 -->
    <bean id="transactionManager" 
          class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
 </beans>
从上面的配置文件可以看出,当采用Spring事务管理策略时,应用程序无须与具体的事务策略耦合。Spring提供了两种事务管理方式:

① 编程式事务管理:即使利用Spring编程式事务时,程序也可直接获取容器中的transactionManager Bean,该Bean总是PlatformTransactionManager的实例,所以可以通过该接口提供的3个方法来开始、提交事务和回滚事务。

② 声明式事务管理:无须在Java程序中书写任何的事务操作代码,而是通过在XML文件中为业务组件配置事务代理,AOP为事务代理所织入的增强处理也由Spring提供:在目标方法执行之前,织入开始事务;在目标方法执行之后,织入结束事务。

不论采用何种持久化策略,Spring都提供了一致的事务抽象,因此,应用开发者能在任何环境下,使用一致的编程模型。无须更改代码,应用就可在不同的事务管理策略中切换。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值