Spring Framework--Data Access(1)--Transaction Management(2)

三、声明式事务管理的回滚

(1)推荐使用抛出异常的方式来通知Spring的事务框架一个事务需要被回滚,Spring的事务框架会捕捉调用栈上没有处理的异常,然后决定是否需要回滚事务。

(2)默认情况下,Spring事务框架只在事务执行中发生了runtime,unchecked exception异常时,事务才会被回滚。一般的checked exception默认情况下是不会回滚事务的。

(3)你可以配置哪种类型的异常需要引起事务回滚,包括checked exception,比如:

<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
    <tx:method name="get*" read-only="true" rollback-for="NoProductInStockException"/>
    <tx:method name="*"/>
  </tx:attributes>
</tx:advice>

(4)你也可以配置那种类型的异常不要引起事务回滚,比如:

<tx:advice id="txAdvice">
  <tx:attributes>
    <tx:method name="updateStock" no-rollback-for="InstrumentNotFoundException"/>
    <tx:method name="*"/>
  </tx:attributes>
</tx:advice>

(5)当Spring的事务框架捕捉了一个异常时,它会查看配置的回滚规则,最匹配的规则将会被采用,比如下面配置了除InstrumentNotFoundException之外的所有异常都要引起事务回滚:

<tx:advice id="txAdvice">
  <tx:attributes>
    <tx:method name="*" rollback-for="Throwable" no-rollbackfor="InstrumentNotFoundException"/>
  </tx:attributes>
</tx:advice>

(6)你也可以采用编程的方式在异常发生时回滚事务,虽然也很简单,不过这种方式对客户代码来说是侵入性的,和事务API紧耦合了,如果可能的话,强烈推荐事务声明式事务回滚。编程式事务回滚举例:

public void resolvePosition() {
  try {
    // some business logic...
  } catch (NoProductInStockException ex) {
    // trigger rollback programmatically
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
  }
}

四、使用@Transactional注解

除了使用xml方式配置事务外,我们还可以使用注解的方式来配置。@Transactional注解可以放到一个接口,接口的方法,一个类或者类的公共方法签名。如下,@Transactional放在一个类的前面。

// the service class that we want to make transactional
@Transactional
public class DefaultFooService implements FooService {
  Foo getFoo(String fooName);
  Foo getFoo(String fooName, String barName);
  void insertFoo(Foo foo);
  void updateFoo(Foo foo);
}

仅仅有@Transactional注解还不够激活一个事务行为,它只是一个元数据,必须有能够识别它的事务框架。比如为了使上面的注解生效,我们需要在xml文件使用<tx:annotation-driven>标签来对事务行为进行开关。

<!-- from the file context.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 service object that we want to make transactional -->
  <bean id="fooService" class="x.y.service.DefaultFooService"/>
  <!-- enable the configuration of transactional behavior based on annotations -->
  <tx:annotation-driven transaction-manager="txManager"/><!-- a PlatformTransactionManager is still required -->
  <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!-- (this dependency is defined somewhere else) -->
    <property name="dataSource" ref="dataSource"/>
  </bean>
  <!-- other <bean/> definitions here -->
</beans>

<tx:annotation-driven/>标签的transaction-manager属性在它的名字为tansactionManager的时候可以省略不写,否则必须显式的指定,比如上面的txManager。

<tx:annotation-driven/>标签的还有mode("proxy","aspectj")属性,proxy-target-class(true,false)属性,order属性可以配置。

五、事务传播Transaction Propagation

原文地址:https://www.cnblogs.com/winson/p/3686300.html