标签:enter aci 必须 ble 说明 付出 单元 不同的 统计
数据库标准提出了 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) 是数据库最高的隔离级别,所有的事务都按顺序执行。它可以克服前面的隔离级别中出现的各种问题,能够完全保证数据的一致性。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | √ | √ | √ |
读已提交 | × | √ | √ |
可重复读 | × | × | √ |
串行化 | × | × | × |
不同的隔离级别能够在不同程度上压制丢失更新,使用更高的隔离级别能够更好地保证数据的一致性,但是也要付出性能的代价。隔离级别越高,性能越是直线地下降。
标签:enter aci 必须 ble 说明 付出 单元 不同的 统计
原文地址:https://www.cnblogs.com/cloudfloating/p/11783110.html