zoukankan      html  css  js  c++  java
  • 事务与隔离级别

    事务的基本特征 ACID

    • Atomic(原子性):事务中所有的操作是一个整体单元,这个单元中的操作要么全部成功,要么全部失败,不会出现部分失败、部分成功的场景;
    • Consistency(一致性):事务在完成时,必须使所有的数据都保持一致的状态(约束 a + b = 10,事务结束后 a + b = 10 仍然成立);
    • Isolation(隔离性):各个事务在一定程度上感觉不到其他事务的存在(体现在不同的隔离级别上);
    • Durability(持久性):事务提交后,所有的数据都会永久写入到磁盘。

    事务的隔离级别

    数据库标准提出了 4 类隔离级别,在不同程度上压制更新丢失。

    1. 读未提交
    2. 读已提交
    3. 可重复读
    4. 串行化

    读未提交

    读未提交(read uncommitted) 是最低的隔离级别,允许一个事务读取另一个事务没有提交的数据。适合对于数据一致性没有要求的场景。它存在脏读的现象,如下表:

    时刻 事务 1 事务 2 说明
    T1 读取库存为 2 库存为 2
    T2 库存 - 1 库存为 1
    T3 库存 - 1 库存为 0(读取到事务 1 没有提交的数据)
    T4 提交事务 库存保存为 0
    T5 回滚 库存为 0(第一类丢失更新已经克服)

    第一类丢失更新:一个事务回滚,另一个事务提交,回滚覆盖了提交的数据。目前的数据库都克服了第一类丢失更新。

    读已提交

    读已提交(read committed) 是指一个事务只能读取另一个事务已提交的数据,不能读取未提交的数据。

    时刻 事务 1 事务 2 说明
    T1 读取库存为 2 库存为 2
    T2 库存 - 1 事务 1 中库存为 1
    T3 库存 - 1 事务 2 中库存为 1(事务 1 未提交)
    T4 提交 库存保存为 1
    T5 回滚事务 库存为 1 (第一类丢失更新已经克服)

    上表中的操作结果最终正确。但是读已提交会产生不可重复读

    时刻 事务 1 事务 2 说明
    T1 读取库存为 1 库存为 1
    T2 库存 - 1 事务 1 中库存为 0
    T3 读取库存为 1 事务 2 认为可以扣减(事务 1 未提交)
    T4 提交 库存保存为 0
    T5 库存 - 1 失败,此时库存为 0

    这里事务 2 在事务 1 提交之前认为可以扣减,而后来事务 2 扣减时发现库存已经为 0 无法扣减,这样的现象称为不可重复读,这就是读已提交的一个不足。

    可重复读

    可重复读(read repeatable) 的目标是克服读已提交中出现的不可重复读的现象。

    时刻 事务 1 事务 2 说明
    T1 读取库存为 1 库存为 1
    T2 库存 - 1 事务 1 中库存为 0
    T3 读取库存 事务 2 不能读取,等待事务 1 提交
    T4 提交 库存保存为 0
    T5 读取库存 库存为 0,无法扣减

    当事务 2 读取事务 1 事先读取的数据时,会被阻塞,直到事务 1 提交后事务 2 才能读取,读已提交中出现的不可重复读现象消失了。但是可重复读会出现幻读:

    时刻 事务 1 事务 2 说明
    T1 查询库存 100 库存 100,10 个订单
    T2 查询订单为 10
    T3 库存 - 1
    T4 插入订单
    T5 提交 库存 99,11 个订单
    T6 打印订单,11 单 事务 2 中多了一条记录,与之前查询的不一致

    上表出现的就是幻读现象,幻读不是针对一条数据库记录而言,而是多条记录,上表中订单是多条记录统计出来的,它会产生幻读。

    串行化

    串行化(serializable) 是数据库最高的隔离级别,所有的事务都按顺序执行。它可以克服前面的隔离级别中出现的各种问题,能够完全保证数据的一致性。

    总结

    隔离级别 脏读 不可重复读 幻读
    读未提交
    读已提交 ×
    可重复读 × ×
    串行化 × × ×

    不同的隔离级别能够在不同程度上压制丢失更新,使用更高的隔离级别能够更好地保证数据的一致性,但是也要付出性能的代价。隔离级别越高,性能越是直线地下降。

  • 相关阅读:
    Windows环境下消息中间件RabbitMq的搭建与应用
    6.异常释放锁的情况
    5.synchronized锁重入
    4.脏读
    3.多线程(同步、异步)
    2.多线程(同步类级别锁)
    1.多线程同步
    24.Semaphore
    23.读写锁ReadWriteLock
    22.线程通信Condition
  • 原文地址:https://www.cnblogs.com/colorchild/p/14122525.html
Copyright © 2011-2022 走看看