SERIALIZABLE隔离级别可以确保,如果一个查询语句多次执行,不会有数据改变。换句话说,在一个事务里执行相同的查询语句两次,查询出来的数据是一样的,我们将不会看到phantoms。
举个例子
-- Open two new connections
-- Step 1:
-- In the first connection, start a transaction
USEIsolationDB ;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE ;
BEGIN TRAN
SELECT *
FROM IsolationTest
WHERE col1 BETWEEN 20 AND 40 ;
--<EXECUTE>
第一步,先查询一下,事务是开着的状态,即使查询语句已经结束了。
-- Step 2:
-- In the second connection, insert new data
USE IsolationDB
INSERT INTO IsolationTest
VALUES (35, 'Another New Row' ) ;
-- Notice that the INSERT will block
--<EXECUTE>
第二步,插入一条新记录,发现这个insert是一直处于堵塞状态,执行不了。
-- Step 3:
-- Go back to the first connection and rerun the SELECT
SELECT *
FROM IsolationTest
WHERE col1 BETWEEN 20 AND 40 ;
--<EXECUTE>
-- Notice no new rows
第三步,再次执行那个查询语句,返回的结果是一样的。
为了阻止phantoms,是需要代价的。除了要锁住所有的正在被读取的数据外,还要执行SERIALIZABLE隔离级别。