事务的隔离级别(Transaction isolation levels)4

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

REPEATABLE READ

REPEATABLE READ能够保证如果一个事务重复读取那段数据,或者一个查询语句在一个事务里调用两次,返回的数据是一样的。换句话说,两条相同的查询语句在一个事务里执行去读取一些数据,是不会发生读取到两次不一样的数据,这种情况。第二个事务不能修改正在被第一个事务读取的数据。只要这第一个数务还没有提交或者回滚。

举个例子


-- Step 1:
-- Read data in the Repeatable Read isolation level
USE IsolationDB ;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ ;
BEGIN TRAN
SELECT AVG(col1)
FROM IsolationTest ;
--

第一个事务读取数据,但未提交事务,这样会使另外的事务被堵塞。

-- Step 2:
-- In the second connection, update the table:
USE IsolationDB ;
UPDATE IsolationTest
SET col1 =5000
WHERE col1 =500 ;
--

第二步,update语句会堵塞,

-- You should notice that the UPDATE process blocks, 
-- and returns no data or messages
-- Step 3:
-- Go back to the first connection and 
-- run the same SELECT statement:
SELECT AVG(col1)
FROM IsolationTest ;
--
第三步,返回的结果还是原来的未修改过的。

阻止non-repeatable reads, 或者说让第一个事务能够重复读取相同的数据,需要代价。这个额外的代价就是SQLSERVRE 要持有所有的锁直到事务的完成或者回滚。

 REPEATABLE READ级别不能阻止 read phenomena.它只能保护已经在被读的数据,如果你插入新的数据,不去修改原来的正在被读取的数据,那么就会产生phenomena。

举个例子,

-- Close all connections and open two new ones
-- Step 4:
USE IsolationDB ;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRAN
SELECT *
FROM IsolationTest
WHERE col1 BETWEEN 20 AND 40
--
-- Step 5:
-- In the second connection, insert new data
USE IsolationDB ;
INSERT INTO IsolationTest
VALUES (25, 'New Row' ) ;
--
插入了新的一行。
-- Step 6:
-- Go back to the first connection and rerun the SELECT 
SELECT *
FROM IsolationTest
WHERE col1 BETWEEN 20 AND 40 ;
---- Notice one additional row



再次读取,新的一行也被读取了,这个出现的新的一行,叫phantom.这一行在第一次执行SELET语句时是不存在的,数据没有被锁住。要阻止phantoms只能用SERIALIZABLE隔离级别了。








转载于:https://my.oschina.net/cfanyjr/blog/183906

你可能感兴趣的:(事务的隔离级别(Transaction isolation levels)4)