事务相关面试知识点(持续更新)

1.什么是事务

事务是访问数据库的一个操作序列,数据库应用系统通过事务来完成对数据库的存取。事务的正确执行使得数据库从一个状态转换为另一个状态

事务有 ACID 的原则:

  • 原子性(atomicity):即不可分割,事务要么全部被执行,要么全部不被执行,如果事务中所有的子事务全部提交成功,则所有的数据库操作都被提交,数据库状态会发生变化;如果有子事务失败,则其他子事务的数据库操作全部被回滚,数据库回到执行事务之前的状态,不回发生状态变化

  • 一致性(consistency):事务的执行使数据库从一种正确状态转换为另一种正确状态

  • 隔离性(isolation):在事务正常提交之前,不允许把该事务对数据库数据的任何改变提供给其他事务,即在事务正确提交之前,它可能的结果对其他事务不可见

  • 持久性(durability):事务正确提交之后,其结果将永远保存在数据库中,即使在事务提交之后有了其他故障,事务的处理结果也会得到保存

2.并发下事务会产生的问题

  • 脏读:事务 A 读到了事务 B 还没有提交的数据

  • 幻读:一个事务在前后两次查询同一范围的时候,后一次查询看到了前一次查询没有看到的行

  • 不可重复读:事务 A 首先读取了一条数据,执行逻辑的时候,事务 B 将这条数据改变了,然后事务 A 再次读取的时候,发现数据不匹配了

3.Spring 事务的隔离级别

  • default:默认隔离级别,Spring 将使用数据库默认的隔离级别

  • read_uncommitted:读未提交,能够读取到没有被提交的数据,导致脏读,幻读,不可重复读

  • read_committed:读已提交,能够读取到已经被提交的数据,能解决脏读,导致幻读和不可重复读

  • repeatable_read:重复读取,即在数据读出来之后加锁,解决了脏读,不可重复读,无法解决幻读

  • serializable:串行化,最高的事务隔离级别,解决了以上所有问题,性能差,行级锁

mysql 默认的事务隔离级别是 repeatable_read

4.Spring 事务传播机制

  • REQUIRED:支持当前事务,如果没有事务会创建一个新的事务

  • REQUIRED_NEW:挂起当前事务,创建一个新的事务

  • MANDATORY:支持当前事务,如果当前不存在事务则抛出异常

  • SUPPORTS:支持当前事务,如果当前没有事务会以非事务方式执行

  • NOT_SUPPORTED:以非事务方式执行,如果当前存在事务则将当前事务挂起

  • NESTED:如果当前存在事务,则在嵌套事务内执行,如果当前不存在事务,则会创建一个新的事务

  • NEVER:以非事务方式执行,如果当前存在事务抛出异常

Spring @Transactionl 注解什么时候失效

在 spring aop 代理下,只有目标方法被外部调用,目标方法才由 spring 生成的代理对象来管理,这会造成自调用问题

若同一类中的其他方法没有@Transactionl 注解的方法内部调用有@Transactionl 注解的方法,有@Transactionl 注解的方法的事务会被忽略,不会发生回滚

@Transactional 只能被应用到 public 方法上