Spring Boot中的事务管理

什么是事务

在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步操作的结合。由于数据操作在顺序执行的过程中,任何一步操作都有可能发生异常,异常会导致后续操作无法完成,此时由于业务逻辑并未正确的完成,之前成功操作数据的并不可靠,需要在这种情况下进行回退。

事务的作用就是为了保证用户的每一个操作都是可靠的,事务中的每一步操作都必须成功执行,只要有发生异常就回退到事务开始未进行操作的状态。
事务管理是Spring框架中最为常用的功能之一,我们在使用Spring Boot开发应用时,大部分情况下也都需要使用事务。

事务管理是应用系统开发中必不可少的一部分。Spring 为事务管理提供了丰富的功能支持。
Spring 事务管理分为编程式和声明式的两种方式。
编程式事务指的是通过编码方式实现事务;声明式事务基于 AOP,将具体业务逻辑与事务处理解耦。
声明式事务管理使业务代码逻辑不受污染, 因此在实际使用中声明式事务用的比较多。
声明式事务有两种方式,一种是在配置文件(xml)中做相关的事务规则声明,另一种是基于 @Transactional 注解的方式。
本文将着重介绍基于 @Transactional 注解的事务管理。

Spring Boot配置事务管理

在Spring Boot中,当我们使用了spring-boot-starter-jdbc或spring-boot-starter-data-jpa依赖的时候,框 架会自动默认分别注入DataSourceTransactionManager或JpaTransactionManager。所以我们不需要任何额外 配置就可以用@Transactional注解进行事务的使用。
使用mybatis的话,spring boot 会自动配置一个 DataSourceTransactionManager,我们只需在方法(或者类)加上 @Transactional 注解,就自动纳入 Spring 的事务管理了。

Spring Boot启动类必须要开启事务,配置开启事务注解@EnableTransactionManagement

1
2
3
4
5
6
7
8
9
10
@SpringBootApplication
@EnableTransactionManagement
@tk.mybatis.spring.annotation.MapperScan("com.dxysun.contentsales.dao") //mybatis相关注解
public class ContentsalesApplication {

public static void main(String[] args) {
SpringApplication.run(ContentsalesApplication.class, args);
}

}

在service中启动事务

service实现类,加上@Transactional注解,如果你加在类上,那该类所有的方法都会被事务管理,
如果你加在方法上,那仅仅该方法符合具体的事务。当然我们一般都是加在方法上。因为只有增、删、改才会需要事务。

1
2
3
4
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
public Integer add(Object t) {
return mapper.insert(t);
}

@Transactional 注解的属性介绍

value 和 transactionManager 属性

它们两个是一样的意思。当配置了多个事务管理器时,可以使用该属性指定选择哪个事务管理器。

propagation 属性

事务的传播行为,默认值为 Propagation.REQUIRED。

可选的值有:
REQUIRED :如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
SUPPORTS :如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
MANDATORY :如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
REQUIRES_NEW :创建一个新的事务,如果当前存在事务,则把当前事务挂起。
NOT_SUPPORTED :以非事务方式运行,如果当前存在事务,则把当前事务挂起。
NEVER :以非事务方式运行,如果当前存在事务,则抛出异常。
NESTED :如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 REQUIRED 。
指定方法:通过使用 propagation 属性设置,例如:

1
@Transactional(propagation = Propagation.REQUIRED)

isolation 属性

事务的隔离级别,默认值为 Isolation.DEFAULT。

可选的值有:
Isolation.DEFAULT : 使用底层数据库默认的隔离级别。对大部分数据库而言,通常这值就是: READ_COMMITTED 。
Isolation.READ_UNCOMMITTED : 该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读和不可重复读,因此很少使用该隔离级别。
Isolation.READ_COMMITTED : 该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。
Isolation.REPEATABLE_READ : 该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。即使在多次查询之间有新增的数据满足该查询,这些新增的记录也会被忽略。该级别可以防止脏读和不可重复读。
Isolation.SERIALIZABLE : 所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
指定方法:通过使用 isolation 属性设置,例如:

1
@Transactional(isolation = Isolation.DEFAULT)

timeout 属性

事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。

readOnly 属性

指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。

rollbackFor 属性

用于指定能够触发事务回滚的异常类型,可以指定多个异常类型。

noRollbackFor 属性

抛出指定的异常类型,不回滚事务,也可以指定多个异常类型。

参考

Spring Boot 中使用 @Transactional 注解配置事务管理
spring boot配置mybatis和事务管理
Spring Boot中的事务管理

打赏

请我喝杯咖啡吧~

支付宝
微信