欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring声明式事务

程序员文章站 2022-07-05 18:19:00
...

Spring提供了对事务的支持,它提供了两种实现方式:编程式声明式。编程式一般用于细粒度的事务,声明式一般用于粗粒度的事务。通常开发中使用的是声明式事务,可以通过简单配置和注解的方式快速无侵入地实现事务。

声明式事务的实现步骤如下:

Step1:添加事务依赖

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>

Step2:Spring配置文件中配置事务管理器、开启注解

    <!-- 配置事务管理器 -->
    <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--配置基于注解的声明式事务-->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

Step3:@Transactionl注解可以用于方法和类(包括接口)上,建议仅在需要的方法上使用此注解

@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)

参数详解

1. propagation(传播行为)

当前事务方法被另一个事务方法调用时,必须指定事务应该如何传播(即被调用的方法如何工作在调用方法的事务中,如:方法可以在现有事务中运行,也可以开启一个新的事务并在自己的事务中运行)。

Spring提供了7种事务的传播行为

  • REQUIRED(默认值)
    必须在一个具有事务的上下文中运行:如果当前没有(外层)事务,就新建一个事务;如果当前存在(外层)事务,则加入到当前(外层)事务中。(如果被调用方法发生异常,那么调用方法和被调用方法的事务都将回滚)这是最常用的选择。
  • SUPPORTS
    支持当前(外层)事务,如果当前没有(外层)事务,就以非事务方式执行。
  • MANDATORY
    强制使用当前(外层)事务,如果当前没有(外层)事务,就抛出异常。
  • REQUIRES_NEW
    新建一个事务,并在该事务中运行,如果当前存在(外层)事务,则先将当前(外层)事务挂起
  • NOT_SUPPORTED
    以非事务方式执行操作:如果当前存在(外层)事务,就把当前(外层)事务挂起。
  • NEVER
    以非事务方式执行:如果当前存在(外层)事务,则抛出异常。
  • NESTED
    以嵌套方式执行:如果当前存在(外层)事务,则以嵌套方式独立运行于自己的事务中,不影响当前(外层)事务,而当前(外层)事务如果回滚,则该事务也必须回滚;如果当前不存在(外层)事务,则执行与PROPAGATION.REQUIRED类似的操作。
2. isolation(隔离级别)

Spring声明式事务提供了对数据库事务隔离级别的支持(事务隔离级别的介绍可以看我的另一篇文章:数据库事务

  • DEFAULT
    使用数据库默认的事务隔离级别
  • READ_UNCOMMITTED
    允许读取尚未提交的修改,可能导致脏读、幻读和不可重复读
  • READ_COMMITTED
    允许从已经提交的事务读取,可防止脏读,但幻读、不可重复读仍然有可能发生
  • REPEATABLE_READ
    对相同字段的多次读取的结果是一致的,除非数据被当前事务自身修改。可防止脏读和不可重复读,但幻读仍有可能发生
  • SERIALIZABLE
    完全服从ACID隔离原则,确保不发生脏读、不可重复读、和幻读,但执行效率最低。
3. readOnly

指定事务是否为只读,表示该事务是否只读取数据但不更新数据,只有读取操作的事务设置为只读可以帮助数据库引擎优化事务。

4. timeout

事务的开始往往都会发生数据库的表锁或者被数据库优化为行锁,如果允许时间过长,那么这些数据会一直被锁定,影响系统的并发性。为了尽量缩短事务执行时间,可以给这些事务设置超时时间,以秒为单位。

5. rollbackFor、noRollbackFor等

默认情况下,Spring声明式事务默认对所有的运行时异常进行回滚,如有特殊情况可以通过上rollbackFor、noRollbackFor等进行特殊的指定。(一般情况下不会用到)