Transaction Processing
接上文
数据库系统之事务处理-1
https://blog.csdn.net/Jifu_M/article/details/112477560
正确性 (Correctness)
如果同一组事务存在可能的串行执行,使得在两次执行中,每个事务读取相同的值,并且数据库的最终状态相同,则数据库事务的并发执行是视图序列化的( view serializable)。
当数据库事务是可序列化的时,并发执行是正确的。
数据库事务可序列化执行的示例:
--T1 T2
read(x)
write(x, x-10)
read(x)
read(y)
write(y,y+10)
read(y)
上述数据库事务的执行是视图可串行化的,因为存在相同事务的串行执行,这样在两次执行中,事务读取相同的值和
数据库的所有状态都是相同的
与上个例子中中的并发执行等价的串行执行:
--T1 T2
read(x)
write(x, x-10)
read(y)
write(y,y+10)
read(x)
read(y)
然而,视图可序列化性的问题是我们需要花费很多时间来检查数据库操作的执行是否违反了视图可串行性正确性标准。
一个更实用的正确性标准是冲突串行化(confliict serializability)。
如果存在同一组事务的可能串行执行,使得在两次执行中冲突操作的顺序相同,则数据库事务的并发执行是可冲突串行化的。
如果两者都访问相同的数据项,其中一个或两个都是写操作,那么这两个操作就是冲突操作。
read write
read NO YES
write YES YES
换言之,只要其中一个人进行write的操作,那么就会引起冲突操作。
如果存在同一组事务的可能串行执行,使得在两次执行中冲突操作的顺序相同,则数据库事务的并发执行是冲突串行化的(conflict serializable)。
冲突串行化的例子:
--T1 T2
read(x)
write(x, x-10)
read(x)
read(y)
write(y,y+10)
read(y)
冲突操作的顺序是先T1后T2。
非冲突串行化的例子:
T1 T2 x = $100
read(x) x = $100
read(x) x = $100
write(x,x-10) x = $90
write(x,x+20) x = $120
commit x = $120
commit x = $120
冲突操作的顺序是先T1后T2,之后又先T2后T1。这意味着T1和T2的并发执行不可能串行化。
保序可串行化(Order preserving serializability)
如果冲突可串行化和所有非交错事务在原始执行和某些相应的串行执行中具有相同的顺序,那么数据库事务的并发执行是保序冲突串行化的。
每个保序冲突可串行化执行都是冲突可串行化的。
冲突可串行化的执行可能不能是保序冲突可串行化的。
举个冲突可序列化和保持顺序的可串行化执行例子:
T1 T2 T3
write(y,10)
write(x, 10)
read(x)
write(y,20)
先T3后T1之后先T1再T2。
再举个冲突可序列化和非保序可串行化执行例子:
T1 T2 T3
write(x, 10)
read(x)
write(y,10)
write(y,20)
顺序是先T1后T2,之后先T2后T3,与上面第一个例子不同。
可恢复执行(Recoverable executions)
事务管理员必须提供事务的全有或全无属性,即使在出现各种类型的故障时也是如此。
如果每个read由另一个事务T’写入的数据项的事务T在T’commit之后commit,则执行是可恢复的。
举一个不可恢复的例子:
T1 T2 x = $100
read(x)
write(x,x-10) x = $90
read(x) x = $90
write(x,x+20) x = $110
commit x = $110
abort x = $100
Cascadeless executions
如果没有一个事务读取任何其他未commit或abort的事务所写的数据项,则执行是cascadeless的。
举一个例子:
T1 T2 x = $100
read(x) x = $100
write(x,x-10) x = $90
read(x) wait x = $90
abort x = $90
write(x,x+20) x = $120
T1在进行写操作后没有commit,T2在T1退出后再进行写操作会作用在初始的$100上。
Noncascadeless执行的例子:
T1 T2 x = $100
read(x) x = $100
write(x,x-10) x = $90
read(x) x = $90
write(x,x+20) x = $110
abort x = $100
forced abort x = $100
T1在进行写操作后没有commit,T2在读取T1未commit的操作后再进行写操作,然而T1直接abort导致T2进行的写操作作废。
严格执行 (Strict executions)
如果任何数据项d是由事务T写入的,那么任何其他事务都不能读或写数据项d,直到事务T commit或abort。
举一个严格执行的例子:
T1 T2 x = $100
read(x) x = $100
write(x,x+10) x = $110
write(x,20) wait x = $110
abort x = $100
write(x,20) x = $20
commit x = $20
可以看到T2在T1abort之前都无法对数据x进行读写操作。
举一个非严格执行的例子:
T1 T2 x = $100
read(x) x = $100
write(x,x+10) x = $110
write(x,20) x = $20
commit x = $20
abort x = $100
T1的abort导致数据库回滚,破坏了T2进行的写操作。
各个执行之间的关系
下一篇文章我会介绍一下如何画可串行化的图,串行图测试协议,两段锁协议(2PL)和时间戳排序协议。
References
- T. Connoly, C. Begg, Database Systems, A Practical Approach to Design, Implementation, and Management, Chapter 22.1 Transaction Support, Chapter 22.2 Concurrency Control, Pearson Education Ltd, 2015.