这是最高层次isolation level,这个层次的isolation实现了串行化的效果,即:几个Transcation在执行时,其执行效果和某个串行序执行这几个Transaction的效果是一样的。使用Serializable层次的事务,其中的查询语句在每次都必须在同样的数据上执行,从而防止了phantom read,其实现机制是range lock。与下一个层次的不同之处在于range lock。
在基于锁的DBMS中,Serializable直到事务结束才释放select数据集上的读、写锁。而且select查询语句必须首先获得range-locks才能执行。在非锁并行的DBMS中,系统每当检测到write collision时,一次只有一个write能被写入。Range lock记录Serializable Transaction所读取的key值范围,阻止其他在这个key值范围内的记录被插入到表中。Range lock位于Index上,记录一个起始Index和一个终止Index。在Range lock锁定的Index范围内,任何Update、Insert和Delete操作都是被禁止的,从而保证了Serializable中的操作每次都在同样的数据集上进行。
id | name | age |
---|---|---|
1 | Joe | 20 |
2 | Jill | 25 |
事务T1在读取事务T2已经修改、但T2还未提交的数据时会发生Dirty Read。这个Isolation Level唯一能保证的是Update操作按顺序执行,即事务中前面的update一定比后面的update先执行。
下面的这个例子是一个典型的Dirty Read
Transaction 1 | Transaction 2 |
---|---|
/* Query 1 */ SELECT age FROM users WHERE id = 1; /* will read 20 */ |
|
/* Query 2 */ UPDATE users SET age = 21 WHERE id = 1; /* No commit here */ |
|
/* Query 1 */ SELECT age FROM users WHERE id = 1; /* will read 21 */ |
|
ROLLBACK; /* lock-based DIRTY READ */ |
在一个事务T1中,如果对同一条记录读取两次而值不一样,那么就发生了Non-repeatable read。
在基于锁的DBMS中,Non-repeatable read可能在未获得read lock时进行select操作,或在select操作刚结束就释放read lock时发生。在多版本并行控制的DBMS中,non-repeatable read可能在违背“受commit conflict影响的事务必须回滚“的原则时发生。
Transaction 1 | Transaction 2 |
---|---|
/* Query 1 */ SELECT * FROM users WHERE id = 1; |
|
/* Query 2 */ UPDATE users SET age = 21 WHERE id = 1; COMMIT; /* in multiversion concurrency control, or lock-based READ COMMITTED */ |
|
/* Query 1 */ SELECT * FROM users WHERE id = 1; COMMIT; /* lock-based REPEATABLE READ */ |
有两种方式来防止non-repeatable read。第一种方式用锁使T1和T2串行。另外一种方式是在多版本并行控制的DBMS中使用的。在这里,T2可以提交,而先于T2启动的T1则在自己的Snapshot(快照)里继续执行,在T1提交时,系统会检查其结果是否与T1、T2序执行的结果一样,如果一样,则T1提交,否则T1必须回滚并生成一个serialization failure。
Phantom read是指在一个事务中,执行两个或多个同样的查询返回的结果集却不相同的现象。这种现象发生在没获得range lock即进行select... where....操作时,解决方法是使用range lock。
Transaction 1 | Transaction 2 |
---|---|
/* Query 1 */ SELECT * FROM users WHERE age BETWEEN 10 AND 30; |
|
/* Query 2 */ INSERT INTO users VALUES ( 3, 'Bob', 27 ); COMMIT; |
|
/* Query 1 */ SELECT * FROM users WHERE age BETWEEN 10 AND 30; |
参考:
http://msdn.microsoft.com/en-us/library/ms191272.aspx
http://en.wikipedia.org/wiki/Isolation_%28database_systems%29