一、事务的概念和意义
事务是访问并可能更新各种数据项的一个程序执行单元。它由指令集和构成为单一的、不可分割的单元。tadui3
事务的四个特性:ACID
- 原子性:事务的所有操作在数据库中要么全部正确反映出来,要么完全不反应
- 一致性:隔离事务时(或者说没有其他事务并发执行时),应当保持数据库库的一致性。
- 隔离性:尽管多个事务可能并发执行,但系统应当保证,对于任何一对事务 T i 和 T j T_i和T_j Ti和Tj,两者都感觉不到对方在并发执行
- 持久性:一个事务成功完成后,他对数据库的改变必须是永久的,即使是出现系统故障
二、事务的原子性和持久性
事务并不是中能成功地执行完成,此时称事务为被中止(aborted)。为了维持事务的原子性,所有被终止的事务都应当进行回滚操作(roll back)。事实上事务的状态有以下若干种:
- 活动的额(active):事务在开始和执行时属于这个状态
- 部分提交的(partially committed):最后一条语句执行后但未提交完成的状态
- 失败的(failed):发现正常的执行不能继续后
- 中止的(aborted):事务回滚并且数据库已恢复到事务开始执行前的状态后
- 提交的(committed):成功完成后。
如果事务是提交的或是中止的,它被称为已结束的(terminated)。
三、事务隔离性
并发执行能够:
- 提高吞吐率和资源利用率
- 减少等待时间
四、可串行化
对read和write指令,顺序是重要的,会出现以下情况(其中I和J分别属于事务 T i , T j T_i,T_j Ti,Tj的一条指令):
指令 | 情况 |
---|---|
I = r e a d ( Q ) , J = r e a d ( Q ) I=read(Q),J=read(Q) I=read(Q),J=read(Q) | I与J的顺序无关紧要,因为不论其次序如何,两条指令读取的Q值都是相同的 |
I = r e a d ( Q ) , J = w r i t e ( Q ) I=read(Q),J=write(Q) I=read(Q),J=write(Q) | 此时,若I先于J,则 T i T_i Ti不会读取由 T j T_j Tj的指令J写入的Q值,否则就会读入被写入后的Q值,因此I与J的顺序是重要的 |
I = w r i t e ( Q ) , J = r e a d ( Q ) I=write(Q),J=read(Q) I=write(Q),J=read(Q) | 次序是重要的,类型同前 |
I = w r i t e ( Q ) , J = w r i t e ( Q ) I=write(Q),J=write(Q) I=write(Q),J=write(Q) | I与J的次序影响了Q的最终值 |
可以看到,当I与J至少有一个write指令时,两条指令的顺序是重要的,所以此时称I与J是冲突的(conflict)。另外应当注意到,冲突指令是针对操作一个数据项的指令,对不同数据项的read/write指令不会构成冲突
冲突可串化的定义
如果调度S可以经过一系列非冲突指令交换转换成 S ′ S' S′,则二者是冲突等价(conflict equivalent)的。如果调度S与一个串行调度冲突等价,则调度S是冲突可串行化(conflict serializable)的。
优先图(percedence graph)
优先图 G = ( V , E ) G=(V,E) G=(V,E)由满足以下三个条件之一的边 T i → T j T_i\rightarrow T_j Ti→Tj组成:
- 在 T j 执 行 r e a d ( Q ) 之 前 , T i 执 行 w r i t e ( Q ) 在T_j执行read(Q)之前,T_i执行write(Q) 在Tj执行read(Q)之前,Ti执行write(Q)
- 在 T j 执 行 w r i t e ( Q ) 之 前 , T i 执 行 r e a d ( Q ) 在T_j执行write(Q)之前,T_i执行read(Q) 在Tj执行write(Q)之前,Ti执行read(Q)
-
在
T
j
执
行
w
r
i
t
e
(
Q
)
之
前
,
T
i
执
行
w
r
i
t
e
(
Q
)
在T_j执行write(Q)之前,T_i执行write(Q)
在Tj执行write(Q)之前,Ti执行write(Q)
如果调度S的优先图有环,则它是非冲突可串行化的,否则就是冲突可串行化的
事务的隔离性和原子性
可恢复调度:对于每对事务
T
i
,
T
j
T_i,T_j
Ti,Tj,如果后者读取了前者缩写的数据项,则前者应先于后者提交
无级联调度:对于每对事务
T
i
,
T
j
T_i,T_j
Ti,Tj,如果后者读取了前者缩写的数据项,则前者必须在后者的这一读操作前提交