zoukankan      html  css  js  c++  java
  • Spring-Transactional

    Spring-Transactional

    事务管理是应用系统开发中必不可少的一部分。Spring 为事务管理提供了丰富的功能支持。

    声明式事务有两种方式,一种是在配置文件(xml)中做相关的事务规则声明,另一种是基于 @Transactional 注解的方式。注释配置是目前流行的使用方式。

    一、注解管理事务的实现步骤

    使用 @Transactional 注解管理事务的实现步骤分为两步。

    第一步,在 xml 配置文件中添加事务配置信息。

    <tx:annotation-driven />
    
    <bean id="transactionManager" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    

    第二步,将 @Transactional 注解添加到合适的方法上,并设置合适的属性信息。

    @Transactional 注解的属性信息

    属性名 说明
    name 当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器。
    propagation 事务的传播行为,默认值为 REQUIRED
    isolation 事务的隔离度,默认值采用 DEFAULT
    timeout 事务的超时时间,默认值为 -1 。如果超过该时间限制但事务还没有完成,则自动回滚事务。
    read-only 指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
    rollback-for 用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。
    no-rollback-for 抛出 no-rollback-for 指定的异常类型,不回滚事务。

    除此以外,@Transactional 注解也可以添加到类级别上。当把 @Transactional 注解放在类级别时,表示所有该类的公共方法都配置相同的事务属性信息。

    方法级别的事务属性信息会覆盖类级别的相关配置信息。

    **@Transactional 注解的标注于类上:**

    @Transactional(propagation= Propagation.SUPPORTS, readOnly=true)
    @Service(value ="employeeService")
    public class EmployeeService
    

    1、 注解方式的事务使用注意事项

    当您对 Spring 的基于注解方式的实现步骤和事务内在实现机制有较好的理解之后,就会更好的使用注解方式的事务管理,避免当系统抛出异常,数据不能回滚的问题。

    1.1、 正确的设置 @Transactional 的 propagation 属性

    本来期望目标方法进行事务管理,但若是错误的配置这三种 propagation,事务将不会发生回滚。

    1. TransactionDefinition.PROPAGATION_SUPPORTS

      如果当前存在事务,则加入该事务;

      如果当前没有事务,则以非事务的方式继续运行。

    2. TransactionDefinition.PROPAGATION_NOT_SUPPORTED

      以非事务方式运行,如果当前存在事务,则把当前事务挂起。

    3. TransactionDefinition.PROPAGATION_NEVER

      以非事务方式运行,如果当前存在事务,则抛出异常。

    1.2、 正确的设置 @Transactional 的 rollbackFor 属性

    默认情况下,如果在事务中抛出了未检查异常(继承自 RuntimeException 的异常)或者 Error,则 Spring 将回滚事务;除此之外的异常,Spring 都不会回滚事务!

    如果在事务中抛出其他类型的异常,并期望 Spring 能够回滚事务,可以指定 rollbackFor。例:

    @Transactional(propagation= Propagation.REQUIRED, rollbackFor= MyException.class)
    

    若在目标方法中抛出的异常是 rollbackFor 指定的异常的子类,事务同样会回滚。

    1.3、@Transactional 只能应用到 public 方法才有效

    只有 @Transactional 注解应用到 public 方法,才能进行事务管理。

    Spring AOP 会检查目标方法的修饰符是不是 public,若不是 public,就不会获取 @Transactional 的属性配置信息,最终会造成不会用 TransactionInterceptor 来拦截该目标方法进行事务管理。

    1.4、 避免 Spring 的 AOP 的自调用问题

    在 Spring 的 AOP 代理下,只有目标方法由外部调用,目标方法才由 Spring 生成的代理对象来管理,这会造成自调用问题。

    若同一类中的其他没有 @Transactional 注解的方法内部调用有 @Transactional 注解的方法,有 @Transactional 注解的方法的事务被忽略,不会发生回滚。

    @Service
    public class OrderService {
        private void insert() {
            insertOrder();
        }
    
        @Transactional
        public void insertOrder() {
            //insert log info
            //insertOrder
            //updateAccount
        }
    }
    

    insertOrder() 方法尽管有 @Transactional 注解,但它被内部方法 insert() 调用,因此 insertOrder() 的事务被忽略,出现异常事务不会发生回滚。

    二、XML配置实现管理事务

    <!--第一步:配置声明式事务-->
    <bean id="transactionManager" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    
    <!--第二步:-->
    <!--结合AOP、实现事务的织入-->
    <!--配置事务的通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
    <!--给哪些方法配置事务-->
    <!--配置事务的传播特性-->
        <tx:attributes>
            <tx:metmod name="方法名1" propagation="REQUIRED"/>
            <tx:metmod name="方法名2" propagation="REQUIRED"/>
            <tx:metmod name="*" propagation="REQUIRED"/><!-- * :代表全部-->
        </tx:attributes>
    </tx:advice>
    
    <!--第三步:-->
    <!--配置事务的切入-->
    <aop:config>
        <!--配置切入点-->
        <aop:pointcut id="txPointCut" expression="execution(* com.xxx.xxx.*.*(..))"/>
        <!--切入-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    </aop:config>
    
  • 相关阅读:
    EntityFramework 启用迁移 EnableMigrations 报异常 "No context type was found in the assembly"
    JAVA 访问FTP服务器示例(2)
    NuGet Package Manager 更新错误解决办法
    JAVA 访问FTP服务器示例(1)
    RemoteAttribute 的使用问题
    诡异的 javascript 变量
    javascript apply用法
    Babun 中文乱码
    GSM呼叫过程
    转站博客园
  • 原文地址:https://www.cnblogs.com/whitespaces/p/12442466.html
Copyright © 2011-2022 走看看