SpringBoot笔记

事务

在SpringBoot中可以使用@Transactional注解使用事务,它可以加在service层的方法上、类上、接口上。

方法前加上@Transactional,则这整个方法是一个事物,方法执行前开启事务,执行成功则提交事务,出现异常执行失败则回滚事务。

在类上用@Transactional则相当于该类的所有方法都加了该注解。

在接口上用@Transactional则相当于该接口的所有实现类都加了该注解。

默认只有出现RuntimeException运行时异常才会触发回滚,我们可以使用该注解中的rollbackFor属性来指定何种异常会触发回滚。

事务的传播行为

当一个事务中嵌套另一个事务时,可以用@Transactional注解的propagation属性指定是开启一个新事务还是加入当前的事务。具体属性值如下:

属性值
含义
REQUIRED (默认)需要事务,有则加入,无则创建新事务
REQUIRES_NEW 需要新事务,无论有无,总是创建新事务
SUPPORTS 支持事务,有则加入,无则在无事务状态中运行
NOT_SUPPORTED 不支持事务,在无事务状态下运行,如果当前存在已有事务,则挂起当前的事务
MANDATORY 必须有事务,否则抛异常
NEVER 必须无事务,否则抛异常

一般只需要关注前面两种情况就可以了。

例举个实际场景,删除用户,同时删除该用户发布的所有帖子,且不论删除成功与否都要记录操作日志:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Transactional(rollbackFor = Exception.class)
public void deleteUserById(Long userId) {
try {
deleteUser(userId);

// 模拟异常
int i = 1 / 0;

deleteAllBlogsById(userId);
} finally {
log("删除了id为" + userId + "的用户");
}
}

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public void log(String msg) {
// ...
}

若不加propagation = Propagation.REQUIRES_NEW,则默认两个方法共用一个事务,当出现异常时,事务回滚,把写入日志的操作也回滚了。