目录
前言
使用场景
1.单个方法层面
2.类级别使用
3.指定异常回滚
4.跨方法调用事务管理
5.只读事务
6.设置超时时间,超时则自动回滚
7.隔离级别设置
章末
前言
小伙伴们大家好,ACID(原子性,一致性,隔离性,持久性)特性相比大家都很熟悉,每种的实现方式也都不同,原子性的要求是指一个操作要么全部执行成功,要么全部失败回滚,不会存在部分成功或者失败的情况,意味着在一个事务中的操作要么全部生效,要么全部取消以此保证数据的一致性和完整性。在SpringBoot 项目中就有@Transactional事务注解,并且可以支持各种场景的使用
使用场景
1.单个方法层面
手动抛出一个运行时异常,postman测试下事务是否回滚,如图在控制台成功打印了插入日志,然后抛出了自定义异常,检查下数据库,确实没有该条数据,测试成功
2.类级别使用
比如 需要控制整个业务实现类都要回滚,可以将注解加到类上方,表明所有方法会在一个事务中执行
@Service
@Transactional
public class UserService {
@Autowired
private UserRepository userRepository;
public void updateUser(User user) {
userRepository.save(user);
}
public void addUser(User user) {
userRepository.add(user);
}
...
}
3.指定异常回滚
在Spring中默认情况下,只有当抛出的异常是 RuntimeException 或者子类时,事务才会回滚,为了让事务在抛出 Exception 也回滚,可以通过自定义配置 rollbackfor 属性来指定需要回滚的异常类型
通过测试发现,控制台正常打印插入日志,然后抛出异常,数据库中不会有该条数据,回滚成功
4.跨方法调用事务管理
在当前使用了事务方法中调用另一个方法,并且该方法需要事务管理,可以使用 Propagation.REQUIRES_NEW 属性开启,如下,把抛出异常的代码块放到单独的方法中,并且将这段调用方法捕获打印
即在同一个类中,saveUser方法会在一个新的事务中执行,不受外部事务的影响
测试结果如下,由于手动捕获的原因,现在可以正确插入数据
5.只读事务
在注解上面开启属性(默认为false) ,则该方法中涉及到的操作限制为只读
测试如图,控制台提示操作失败,原因是该连接限定了只读
6.设置超时时间,超时则自动回滚
测试如下,设置时间为1s (默认单位:秒),看到控制台提示超时信息
7.隔离级别设置
Mysql中的隔离机制默认是可重复读,可以解决幻读(两次查询中间有新数据提交)和不可重复读的问题(两次查询中间有老数据修改),可重复读的原理大概是用到了MVCC(多版本并发控制),第一次查询的时候会生成当前版本的视图,后面查询也是查这里的数据
isolation
:指定事务的隔离级别,默认为Isolation.DEFAULT
。事务隔离级别决定了多个事务之间的相互影响程度。常见的隔离级别包括:
Isolation.DEFAULT
:使用默认的隔离级别。Isolation.READ_UNCOMMITTED
:允许读取未提交的数据变更。Isolation.READ_COMMITTED
:只能读取已提交的数据变更。Isolation.REPEATABLE_READ
:可重复读取相同的数据,直到事务结束。Isolation.SERIALIZABLE
:所有事务依次执行,避免并发问题。
章末
文章到这里就结束了~