1. 什么是事务

    答:既是把操作一次数据库的这个操作当成是一个事务,把这个行为抽象了。

    例如:查询一次user表的所有内容叫一次事务。

  2. 事务的4大特性(ACID):

    • 原子性(Atomicity):一个事务内的操作,要么全部执行成功,要么全部不成功。
    • 一致性(Consistency):事务执行后,数据库状态与其他业务规则保持一致。如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。
    • 隔离性(Isolation):每个事务独立运行。在并发环境中,并发的事务是互相隔离的,互不影响。
    • 持久性(Durability):事务一旦提交后,数据库中的数据必须被永久地保存下来。

  3. 事务的4大隔离级别:

    通过一个转账系统做分析:

    • READ_UNCOMMITTED

      已读但未提交,即一个事务读取到了另一个事务未提交的数据。在这种隔离级别下,会造成“脏读”的情况。如下表

      事务A存款 事务B取款
      事务A开始 ----
      ---- 事务B开始
      ---- 事务B查询余额(10元)
      ---- 事务B取出10元(0元)
      事务A查询余额(0元) ----
      ---- 事务B撤销(10元)
      事务A存款10元(10元) ----
      事务A提交(更新余额:10元) ----

      正常情况下,A、B两事务执行完以后,账户余额应为20元,但是在时刻T5时,事务A查询到的余额为0元,这是因为读取到了事务B未提交的数据,即读到了“脏”数据。

    • READ_COMMITTED

      在这个隔离级别下,可以有效避免“脏读”情况的发生。虽然解决了不可重复读的问题,但是在这个隔离级别下无法避免不可重复读取的问题。在READ_COMMITTED隔离级别下,可能会出现如表13-2所示的场景。如下表

      事务A查询 事务B取款
      事务A开始 ----
      ---- 事务B开始
      ---- 事务B查询余额(10元)
      事务A查询(10元)
      ---- 事务B取出10元(0元)
      ---- 事务B提交(更新余额:0元)
      事务A查询(0元) ----
      事务A提交 ----

      事务A执行了两次余额查询,但第一次查询得到的余额是10元,第二次查询得到的余额为0元,这就是不可重复读取的问题。

    • REPEATABLE_READ

      可重复读级别是保证在事务处理过程中多次读取同一个数据时的值始终是一致的。可重复读取是通过在事务开启后不允许其他事务对当前记录进行修改操作实现的。
      这个隔离级别避免了“脏读”和不可重复读的问题,但是有可能会出现“幻读”。“幻读”场景的出现。如下表

      事务A查询 事务B存款款
      事务A开始 ----
      ---- 事务B开始
      事务A查询 ----
      ---- 事务B存入10元
      ---- 事务B提交
      事务A查询 ----
      事务A提交 ----

      在事务A中,同一个事务多次获取交易记录,发现第二次获取交易记录的结果中多出了一笔存款记录——事务B发生的存款操作,对事务A来说,好像是出现了幻觉一样,即“幻读”。

    • SERIALIZABLE

      顺序读是最严格的事务隔离级别。它要求所有的事务排队依序执行,即事务只能一个接一个地处理,不能并发执行。

    • Spring还有一种默认既是根据数据的事务来决定自己的事务

    • 4种事务隔离级别从上往下,级别越高,并发性越差,但安全性越来越高。

      事务隔离级别 脏读 重复读 幻读
      READ_UNCOMMITTED 允许 允许 允许
      READ_COMMITTED 不允许 允许 允许
      REPEATABLE_READ 不允许 不允许 允许
      SERIALIZABLE 不允许 不允许 不允许
  4. 事务的7中传播途径

    答:事务传播行为是用来描述由某一个事务传播行为修饰的方法被嵌套进另一个方法的时候。

    举例子:

    • 首先查询剩余余额算成一个事务

    • 接着定义取款事务

      取款之前先调用查询事务

      这个过程就叫事务的传播

Spring事务知识点(总结)_数据库