1.事务
事务 (Transaction)是数据库操作的最小工作单元,它是一个操作序列,这些操作要么全部执行成功 ,要么全部不执行(回滚到最初状态)
2.Spring编程式事务
Spring ⼿动操作事务和上⾯ MySQL 操作事务类似,有 3 个重要操作步骤:
-
开启事务(获取事务)
-
提交事务
-
回滚事务
SpringBoot 内置了两个对象:
-
DataSourceTransactionManager 事务管理器。⽤来获取事务(开启事务),提交或回滚事务
-
TransactionDefinition 是事务的属性,在获取事务的时候需要将 TransactionDefinition 传递进去从⽽获得⼀个事务 TransactionStatus
@Autowired//注入事务管理器 private DataSourceTransactionManager dataSourceTransactionManager; @Autowired//注入事务配置 private TransactionDefinition transactionDefinition;
//开启事务 TransactionStatus transaction = dataSourceTransactionManager.getTransaction(transactionDefinition);
//提交事务 dataSourceTransactionManager.commit(transaction);
//回滚事务 dataSourceTransactionManager.rollback(transaction);
3.Spring声明式事务
方法/类添加@Transactional,大体上有五种情况:
注:下面提到的异常都是运行时异常,还有其他异常情况不一样 ,在后续**@Transactional详解**中讲解
- 代码正常运行:事务提交
- 代码发生异常:事务回滚
- 代码发生异常,捕获异常并处理:事务提交
- 代码发生异常,捕获异常并抛出:事务回滚
- 代码发生异常,不希望抛出异常并实现回滚:手动实现,**TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();**如下所示
@RequestMapping("/trans") @RestController public class TransController { @Autowired private UserService userService; @Transactional @RequestMapping("/registry") public String registry(String name,String password){ userService.registryUser(name,password); try { int a=10/0; }catch(Exception e){ System.out.println("发生异常"); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } return "注册成功"; } }
4.@Transactional详解
@Transactional是 Spring 框架中用于声明式事务管理的关键注解。它简化了事务编程,通过简单的注解即可实现复杂的事务管理。它包含三种属性
- rollbackFor: 异常回滚属性. 指定能够触发事务回滚的异常类型. 可以指定多个异常类型
- Isolation: 事务的隔离级别. 默认值为 Isolation.DEFAULT
- propagation: 事务的传播机制. 默认值为 Propagation.REQUIRED
(1)rollbackFor
默认只在Error 和抛出/发生运行时异常时发生事务回滚,其他类型不会发生回滚
因此在注解中可以进行设置如:**@Transactional(rollbackFor=Exception.class)**代表发生所有异常时都会回滚
(2)事务隔离级别
(2).1MySQL 事务隔离级别
- 读未提交:a事务进行数据操作但未提交时,b事务能够读到a操作后的数据, 但是 因为a事务可能回滚,b事务读到的数据没有意义,存在脏读问题
- 读已提交:解决脏读问题,a事务操作数据但未提交时,b事务无法读到a操作后的数据 但是 ,当a事务提交之后,b读到的数据和之前读到的数据不一样,存在不可重复读问题
- **可重复读:解决不可重复读问题,b事务不会读到a事务对已有数据的修改,即使已经提交 (默认级别)**但是, 当b事务进行操作时能感知到a对数据进行过操作,存在幻读问题
- 串行化: 对事务序列化,a事务全部执行完之后,才能进行b事务操作,解决上述全部问题, 但是效率低下
(2).2 Spring 事务隔离级别
Spring 中事务隔离级别有5 种:
- Isolation.DEFAULT : 以连接的数据库的事务隔离级别为主.
- Isolation.READ_UNCOMMITTED : 读未提交, 对应SQL标准中 READ UNCOMMITTED
- Isolation.READ_COMMITTED : 读已提交,对应SQL标准中 READ COMMITTED
- Isolation.REPEATABLE_READ : 可重复读, 对应SQL标准中 REPEATABLE READ
- Isolation.SERIALIZABLE : 串⾏化, 对应SQL标准中 SERIALIZABLE
(3)事务传播机制
事务传播机制就是: 多个事务⽅法存在调⽤关系时, 事务是如何在这些⽅法间进⾏传播的.
@Transactional 注解⽀持事务传播机制的设置, 通过 propagation 属性来指定传播⾏为.
Spring 事务传播机制有以下 7 种:
假设a事务调用b事务
- Propagation.REQUIRED : 默认的事务传播级别. 如果a有事务,则b使用a事务;如果a没有,则b创建事务
- Propagation.SUPPORTS : 如果a有事务,则b使用a事务;如果a没有,则b以非事务方式进行
- Propagation.MANDATORY :如果a有事务,则b使用a事务;如果a没有,则b抛出异常
- Propagation.REQUIRES_NEW : 不管a有没有事务,b都开启新事务
- Propagation.NOT_SUPPORTED : 不管a有没有事务,b都以非事务方式运行
- Propagation.NEVER : 以非事务方式运行,如果a有事务,b直接抛异常
- Propagation.NESTED : 如果当前a有事务, 则b创建⼀个事务作为当前事务的嵌套事务来运⾏.如果a没有事务, 则b创建事务