Spring框架事务管理之三:Spring声明式事务

1.Spring声明式事务与JavaEE CMT的对比
JavaEE CMT依赖JTA事务API,Spring声明式事务可以依赖多种事务API
JavaEE CMT只能用于EJB组件,Spring声明式事务可以用于任何类
JavaEE CMT支持事务上下文的跨远程调用传播,Spring事务无能为力
JavaEE CMT只有遇到java.rmi.RemoteException异常时才回滚事务;Spring声明式事务默认与JavaEE CMT一致,但还可以通过声明式的事务回滚规则定制回滚事务的条件


2.Spring声明式事务的实现机制

Spring声明式事务是依赖于Spring的AOP代理机制实现的。

首先,标注或XML的元数据声明与AOP结合生成AOP代理,
然后,AOP代理再通过org.springframework.transaction.interceptor.TransactionInterceptor和具体的PlatformTransactionManager实现类实现对方法调用的事务操作。


3.Spring声明式事务的标注(略)

@javax.transaction.Transactional


4.Spring声明式事务的XML配置

<!-- from the file '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: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.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- this is the object that we want to be made transactional -->
    <bean id="fooService" class="x.y.service.DefaultFooService"/>

    <!-- the transactional advice -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <!-- the transactional semantics... -->
        <tx:attributes>
            <!-- all methods starting with 'get' are read-only -->
            <tx:method name="get*" read-only="true"/>
            <!-- other methods use the default transaction settings -->
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>

    <!-- ensure that the above transactional advice runs for any execution
        of an operation defined by the FooService interface -->
    <aop:config>
        <aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>
    </aop:config>

    <!-- the DataSource -->
    <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>

    <!-- the PlatformTransactionManager -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- other <bean/> definitions here -->

</beans>

说明:

x.y.service.FooService是一个接口,其中定义的逻辑方法将被加入到事务的操作中。x.y.service.DefaultFooService是FooService接口的一个实现。

将逻辑方法加入到事务操作中,是通过<tx:advice>通知实现的。<tx:advice>不仅通过transaction-manager属性指明使用的事务管理器,而且通过<tx:method>子元素指出加入到事务操作中的逻辑方法。

那么逻辑方法究竟什么时候被加入到事务中执行呢?通过<aop:config>给出,其<aop:pointcut>给出进入事务执行的条件,<aop:advisor>则将逻辑方法和进入事务执行的条件结合起来。


默认,在事务执行过程中,只有发生java.rmi.RemoteException异常才会回滚事务。

在定义事务通知<tx:advice>通知时,可以为要加入到事务中的逻辑方法指定回滚的异常,即发生指定异常即回滚该逻辑方法,示例如下:

<tx:method name="*" rollback-for="Throwable" no-rollback-for="InstrumentNotFoundException"/>


此外,还可以为不同的逻辑方法设置不同的进入事务执行的条件,示例如下:

    <aop:config>
        <aop:pointcut id="defaultServiceOperation" expression="execution(* x.y.service.*Service.*(..))"/>
        <aop:pointcut id="noTxServiceOperation" expression="execution(* x.y.service.ddl.DefaultDdlManager.*(..))"/>

        <aop:advisor pointcut-ref="defaultServiceOperation" advice-ref="defaultTxAdvice"/>
        <aop:advisor pointcut-ref="noTxServiceOperation" advice-ref="noTxAdvice"/>
    </aop:config>
    <tx:advice id="defaultTxAdvice">
        <tx:attributes>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
    <tx:advice id="noTxAdvice">
        <tx:attributes>
            <tx:method name="*" propagation="NEVER"/>
        </tx:attributes>
    </tx:advice>


5.补充说明<tx:advice>的设置

默认情况下<tx:advice>设置的事务参数如下:

  • 事务操作为可读写,即read-only="false"
  • 事务隔离级别为DEFAULT,即isolation="DEFAULT"
  • 事务传播类型为REQUIRED,即propagation="REQUIRED"
  • 事务超时为-1,即timeout=-1,即表示采用执行事务的系统的设置
  • 事务回滚的异常为java.rmi.RemoteException



你可能感兴趣的:(spring,AOP,代理,事务,回滚)