有人可以确认我的隔离级别理解

时间:2015-05-27 11:34:41

标签: sql-server-2008

下面提到五种隔离级别摘要...如果我错了请纠正我: -

  1. 阅读不通。在这个级别,我们可以读取脏页面,并且即使没有提交记录,也可以在行上完成(插入和更新等DML语句)。
  2. 读取已提交。只能读取已提交的行。如果在读取记录时事务处于打开状态,则会发生死锁。即使交易未完成,也可以对数据进行修改(插入和更新)
  3. 可重复阅读。将是提交读取+任何更新只能在END TRANSACTION之后发生,但插入命令(幻像插入)将执行更改,即使数据未提交。
  4. 序列化。无法使用INSERT命令插入行,并且niether可以在未提交的事务中使用UPDATE命令,也不能读取未提交的数据
  5. 快照。如果有两个交易T1和T2。只有在提交这两个事务之后才会看到提交的数据。如果这两个事务相互冲突,那么事务将完全失败并且事务将回滚

1 个答案:

答案 0 :(得分:1)

您需要首先了解隔离级别解决的下划线问题。

  1. 肮脏的阅读(我看到更新的记录,但它又消失了)
  2. 不可重复读取(更新 - 我看到了更新的值,但现在值已经有了 改变。哦有人回来了。)
  3. 幻影阅读(插入 - 这看起来像一个鬼然后消失了)
  4. 尝试在两个连接上玩游戏。首先运行连接1脚本然后连接2脚本而不提交任何内容。执行完两个脚本后,尝试提交连接1.

    READ UNCOMMITTED - 在此隔离级别下运行的连接可以读取已modified by other transactions但尚未提交的行。

    READ COMMITTED - 在此隔离级别下运行的连接无法读取已修改但未由其他事务提交的数据。

    REPEATABLE READ - 在此隔离级别下运行的事务无法读取已被修改但尚未由其他事务提交的数据,其他任何事务都无法修改已有的数据在此事务完成之前,此事务已读取此事务。这是通过在此事务读取的记录上放置共享锁来完成的。拥有共享锁定记录,在此事务完成之前,没有其他事务可以修改此记录。

    SERIALIZABLE - 与可重复读取相同的条件,增加了一个条件,即其他事务无法插入新行,其键值将落入由任何语句读取的键范围内当前事务完成之前的当前事务。 将记录视为在日期范围之间插入记录。您正尝试在另一个连接读取的日期范围之间插入记录。

    DIRTY READ

    连接1

    SET TRANSACTION ISOLATION LEVEL READ COMMITTED
    BEGIN TRAN
    
    UPDATE tbl SET Col1 = 'Dummy' WHERE ID = 1
    
    --NO COMMIT YET
    

    连接2

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
    BEGIN TRAN
    
    SELECT * FROM tbl WHERE ID = 1 -- will return you 'Dummy' if script 
                                      on connection 1 executed first. Since transaction on 
                                      connection 1 hasn't been committed yet, you did a dirty 
                                      read on connection 2.
    
    --NO COMMIT YET
    

    避免不可重复读取

    连接1

    SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
    BEGIN TRAN
    
    SELECT * FROM tbl WHERE id = 5 --Issue shared lock.  This prevents 
                                   other transactions from modifying any 
                                   rows that have been read by the current transaction. 
    
    --Not committed yet
    

    连接2

    SET TRANSACTION ISOLATION LEVEL READ COMMITTED
    BEGIN TRAN
    
    SELECT * FROM tbl WHERE id = 5
    UPDATE tbl set name='XYZ' WHERE ID = 5 -- this will wait until transaction
                                           at connection 1 is completed. 
                                          (Shared lock has been taken)
    --Not committed yet
    

    避免幻影阅读

    连接1

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    BEGIN TRAN
    
    SELECT * FROM tbl WHERE Age BETWEEN 5 AND 15 -- This will issue range lock
    
    --Not committed yet
    

    连接2

    SET TRANSACTION ISOLATION LEVEL READ COMMITTED
    BEGIN TRAN
    
    INSERT INTO tbl (Age) VALUES(4) -- Will insert successfully
    INSERT INTO tbl (Age) VALUES(7) -- this will wait until transaction
                                           at connection 1 is completed. 
                                          (Range lock has been taken)
    --Not committed yet