上次介绍到 Lock 的特性,主要是要了解资料库对于资料保护的基本方法,在实务上的运用是要利用 Isolation Level 来做资料存取权限的设定。一般而言,Isolation Level 可以分成四个阶层,层级高的功能会涵盖层级低的功能。
层级 | 名称 | 说明 |
0 | read uncommitted | 允许读取尚在作用中的 transaction 异动过的资料,也就是当资料正在被其他 transaction 异动时,也可以读取该资料。 |
1 | read committed | 只能读取不在 transaction 中异动的资料,也就是当资料正在被其他 transaction 异动时,就不可以读取该资料。 |
2 | repeatable read | 在同一个 transaction 中,同样的 SQL 语法都会得到同样的结果,也就是当资料被读取后,其他的 transaction ,不可以 update 或 delete 该资料。 |
3 | serialized read | 在同一个 transaction 中,同样的 SQL 语法都会得到同样的结果,也就是当资料被读取后,其他的 transaction ,不可以 insert、update 或 delete 该资料。 |
Isolation Level 0 ( read uncommitted )
T1 事件说明 T2 begin transaction T1、T2 两个 transaction 同时启动 begin transaction Update employee Set salary = salary * 1.05 T1 正在做调薪的动作 T2 读取 empid 为 A01 的薪资资料 Select salary From employee Where empid = 'A01' T2 处理结束 commit transaction commit/ rollback transaction T1 处理过程正常 ( commit ),处理过程中有问题,回复到未处理的状态 ( rollback ) 当 T2 以 read uncommitted 的方式读取资料时,所取得的薪资资料,会因为 T1 以 rollback 的方式结束,而取得错误的资料。
Isolation Level 1 ( read committed )
T3 事件说明 T4 begin transaction T3、T4 两个 transaction 同时启动 begin transaction Update employee Set salary = salary * 1.05 T3 正在做调薪的动作 T4 读取 empid 为 A01 的薪资资料 Select salary From employee Where empid = 'A01' commit/ rollback transaction T4 处理过程正常 ( commit ),处理过程中有问题,回复到未处理的状态 ( rollback ) T4 处理结束 commit transaction 当 T3 以 read committed 的方式读取资料时,T4 会等到 T3 执行完成 ( commit/ rollback ),再读取该笔资料,万一 T4 等太久就会发生 Time Out 的现象。
Isolation Level 2 ( repeatable read )
T5 事件说明 T6 begin transaction T5、T6 两个 transaction 同时启动 begin transaction Select sum ( salary ) From emp T5 计算所有的薪资总和 T6 更新 empid 为 A01 的薪资 Update emp Set salary = salary * 1.10 Where empid = 'A01' T6 处理结束 commit transaction Select sum ( salary ) From emp commit transaction T5 处理结束 这里要特别注意的是,T5 重复读取相同的资料,但是在处理的过程中,T6 更新了部分的资料,将导致 T5 无法取得相同的资料。
为避免这个问题, T5 在读取资料时应该采用 Isolation Level 2 的方式,禁止使用 update、delete 的指令,才可以达到所需要的效果。
Isolation Level 3 ( serialized read )
T7 事件说明 T8 begin transaction T7、T8 两个 transaction 同时启动 begin transaction Select sum ( salary ) From emp T7 计算所有的薪资总和 T8 新增一笔 emp 资料 Insert Into emp ( ... ) Values ( ... ) T8 处理结束 commit transaction Select sum ( salary ) From emp commit transaction T7 处理结束 T7 延续 Isolation Level 2 所产生的问题,当 T8 insert 新的资料进来时,将导致 T7 无法取得相同的资料。
为避免这个问题, T7 在读取资料时应该采用 Isolation Level 3 的方式,除了禁止使用 update、delete 的指令,同时也禁止使用 insert 的指令,才可以达到所需要的效果。
至于要使用哪一种 Isolation Level,必须视实际上的需要做设定,没有绝对的处理方法。