有这论文的时候还没我呢,精彩
2 Isolation Definitions
2.1 Serializability Concepts
一个事务将一组行为组合在一起,将数据库从一个正确的状态转换成领域另一个正确的状态(找不到特别好的词语表示consistent,一致性很容易往分布式CAP上联想)。History将互相交织得事务模拟成一系列串行得动作,比如对特定数据内容的读,写。如果两个不同的事务对相同的数据进行操作,至少有一个操作是写,那么两个事务发生冲突。数据内容可以是一行,一页,一表,也可以是一批数据。
特定的history可以生成一个dependency graph,定义了多个事务之间按照时间的数据流,已提交的事务中的每个行为被看作为图上的一个点。
如果事务T1的行为op1与之前的事务T2的行为op2有冲突,<op1,op2>
成为图上的一条边。如果两个history有相同的已提交事务和相同的dependency graph,则成为相同的history。一个serializable的history表示它与一个serial history是相等的。
serial history:if it has the same dependency graph as some history that executes transactions one at a time in sequence.
2.2 ANSI SQL Isolation Levels
P1(Dirty Read)
Transaction T1 modifies a data item. Another transaction T2 then reads that data item before T1 performs a COMMIT or ROLLBACK. If T1 then performs a ROLLBACK, T2 has read a data item that was never committed and so never really existed.
P2(Non-repeatable or Fuzzy Read)
Transaction T1 reads a data item. Another transaction T2 then modifies or deletes that data item and commits. If T1 then attempts to reread the data item, it receives a modified value or discovers that the data item has been deleted.
P3(Phantom)
Transaction T1 reads a set of data items satisfying some <search condition>
. Transaction T2 then creates data items that satisfy T1’s<search condition>
and commits. If T1 then repeats its read with the same <search condition>
, it gets a set of data items different from the first read.
上面三种现象在serial history中是不会发生的。
Isolation Level | P1 Dirty Read | P2 Fuzzy Read | P3 Phantom |
---|---|---|---|
ANSI READ UNCOMMITTED | Possible | Possible | Possible |
ANSI READ COMMITTED | Not Possible | Possible | Possible |
ANSI REPEATABLE READ | Not Possible | Not Possible | Possible |
ANOMALY SERIALIZABLE | Not Possible | Not Possible | Not Possible |
2.3 Locking
基本的串行化定理是well-formed two-phase locking,保证可串行化 ——两阶段锁下的每个历史等同于一些串行历史。相反,如果一个事务不是well-formed two-phase locking的,那么(除了在退化的情况下)可能出现不可串行化的执行历史。 论文定义了四个一致性度,试图说明锁,依赖和基于异常的表征的等价性。
Consistency Level = Locking Isolation Level | Read Locks on Data Items and Predicates (the same unless noted) | Write Locks on Data Items and Predicates (always the same) |
---|---|---|
度(Degree)0 | 不需要 | well-formed写 |
度1=锁读未提交(locking READ UNCOMMITTED) | 不需要 | well-formed写,长写锁 |
度2=锁读已提交(locking READ COMMITTED) | well-formed读,短读锁 | well-formed写,长写锁 |
游标稳定(Cursor Stability见 4.1 节) | well-formed读,游标持有读锁,短谓词锁 | well-formed写,长写锁 |
锁可重复读(locking REPEATABLE READ) | well-formed读,长读锁(对于数据项),短读锁(对于谓词) | well-formed写,长写锁 |
度3=锁可串行化(locking SERIALIZABLE) | well-formed读,长读锁 | well-formed写,长写锁 |
上表根据锁定范围(数据项项或谓词),模式(读或写)及其持续时间(短或长)定义了多个隔离类型。
Remark 1: Locking READ UNCOMMITTED « Locking READ COMMITTED « Locking REPEATABLE READ « Locking SERIALIZABLE
3 Analyzing ANSI SQL Isolation Levels
我们对ANSI与锁的隔离级别作比较,先给出一个结论:
Remark 2. 锁协议定义了至少相应于ANSI的基于phenomena的隔离级别一样强大的锁隔离级别
因此,锁隔离级别至少与同名ANSI级别隔离相当。它们隔离度更强吗?答案是肯定的,即使在最低级别也一样。锁读未提交提供长写锁,以避免我们称之为“脏写”的现象,但ANSI SQL并不排除其基于ANSI 可序列化的异常行为。
4 Other Isolation Types
4.1 Cursor Stability
Cursor Stability目的在于避免丢失更新(一个新级别,这里称其为丢失更新)。
P4 (Lost Update):
The lost update anomaly occurs when transaction T1 reads a data item and then T2 updates the data item (possibly based on a previous read), then T1 (based on its earlier read value) updates the data item and commits. In terms of histories, this is:
r1[x]...w2[x]...w1[x]...c1 (Lost Update)
不论是T2是否commit成功,他的更新都丢失了。
P4 is useful in distinguishing isolation levels intermediate in strength between READ COMMITTED and REPEATABLE READ.
Cursor Stability扩展了READ COMMITTED隔离级别下对于SQL游标的锁行为。其提出游标上的Fetching操作rc(意思是读取游标)。rc要求在游标的当前数据项上保持长读锁,直到游标移动或关闭(可能通过提交关闭)。当然,游标上的Fetching事务可以更新行(wc),即使游标在随后的Fetch上移动,写锁也将保持在行上直到事务提交。 rc1 [x]和以后的wc1 [x]排除了介入的w2 [x]。因此,针对游标上的情况,提出phenomena P4C。
Remark 7: READ COMMITTED « Cursor Stability « REPEATABLE READ
相比读完数据立即释放的 Short duration 读锁,基于游标的锁会将持有时间扩展到游标移动到下一个位置前。
但是还是无法支持RR:
r1[x]...r1[y]...w2[x]...c2...r1[x]...c1
上述情况,两次r1[x]读到的情况不一样。
4.2 Snapshot Isolation
在快照隔离下执行的事务始终从事务开始时起的(已提交)数据的快照中读取数据。事务开始时获取的时间戳称为其开始时间戳(Start-Timestamp)。这一个时间戳可能为事务第一次读之前的任何时间。事务运行在快照隔离中时,只要可以维护其开始时间戳对应的快照数据,在就不会阻塞读。事务的写入(更新,插入和删除)也将反映在此快照中,如果事务第二次访问(即读取或更新)数据,则能再次读到。这个事务开始时间戳之后的其他事务的更新对于本次事务是不可见的。
有了自己的私有空间存放数据,并于其他事务隔离,可以很容易得实现RR级别,当然空间开销也会增加,需要创建很多快照来存放历史版本。
快照隔离是一种多版本并发控制(Multiversion Concurrency Control,MVCC)。它扩展了多版本混合方法(Multiversion Mixed Method),其允许通过只读事务进行快照读(snapshot read)。
当事务T1准备好提交时,它将获得一个提交时间戳(Commit-Timestamp),该值大于任何现有的时间戳。当不存在其他事务T2得提交时间戳在T1事务的间隔[Start-Timestamp,Commit-Timestamp]中,即T1, T2数据不重叠,事务才成功提交,否则,T1将中止。这个功能叫做先提交者成功(First-committer-wins),防止丢失更新(P4)。当T1提交时,其更改对于开始时间戳大于T1的提交时间戳的所有事务都可见。
最引人注目的是,快照隔离没有幻读(在ANSI定义A3的严格意义上)。每个事务都不会看到并发事务的更新。
Remark 9. REPEATABLE READ »« Snapshot Isolation.
快照隔离的“乐观”并发控制方法对于只读事务具有明显的并发优势,但其对更新事务的好处仍然存在争议。这可能不利于长时间运行的与高竞争性短事务执行,长事务容易饿死,因为可能一直发生冲突并失败。当然,当在短期更新事务冲突最小化,长时间运行的事务大多为只读事务的情况下,快照隔离应该有较好的效果。在高数据冲突的长事务中,快照隔离提供了一种古典乐观的方法。对此种情况下的快照隔离的价值存在不同的看法。
5 Summary and Conclusions
隔离级别的概念这篇文章之后就算是过了一遍了,最后贴个原始论文上的表格。