不一致的分析(非重复读)
当第二个事务多次访问同一行而且每次读取不同的数据时,会发生不一致的分析问题。不一致的分析与未确认的相关性类似,因为其它事务也是正在更改第二个事务正在读取的数据。然而,在不一致的分析中,第二个事务读取的数据是由已进行了更改的事务提交的。而且,不一致的分析涉及多次(两次或更多)读取同一行,而且每次信息都由其它事务更改;因而该行被非重复读取。例如,一个编辑人员两次读取同一文档,但在两次读取之间,作者重写了该文档。当编辑人员第二次读取文档时,文档已更改。原始读取不可重复。如果只有在作者全部完成编写后编辑人员才可以读取文档,则可以避免该问题。幻像读
当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围时,会发生幻像读问题。事务第一次读的行范围显示出其中一行已不复存在于第二次读或后续读中,因为该行已被其它事务删除。同样,由于其它事务的插入操作,事务的第二次或后续读显示有一行已不存在于原始读中。例如,一个编辑人员更改作者提交的文档,但当生产部门将其更改内容合并到该文档的主复本时,发现作者已将未编辑的新材料添加到该文档中。如果在编辑人员和生产部门完成对原始文档的处理之前,任何人都不能将新材料添加到文档中,则可以避免该问题。

解决方案 »

  1.   


    四  事务处理的隔离级别使用SET TRANSACTION ISOLATION LEVEL来控制由连接发出的所有语句的默认事务锁定行为从低到高依次是
    READ UNCOMMITTED执行脏读或 0 级隔离锁定,这表示不发出共享锁,也不接受排它锁。当设置该选项时,可以对数据执行未提交读或脏读;在事务结束前可以更改数据内的数值,行也可以出现在数据集中或从数据集消失。该选项的作用与在事务内所有语句中的所有表上设置 NOLOCK 相同。这是四个隔离级别中限制最小的级别。举例设table1(A,B,C)
    A    B    C
    a1   b1   c1
    a2   b2   c2
    a3   b3   c3新建两个连接
    在第一个连接中执行以下语句
    select * from table1
    begin tran
    update table1 set c='c'
    select * from table1
    waitfor delay '00:00:10'  --等待10秒
    rollback tran
    select * from table1在第二个连接中执行以下语句
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
    print '脏读'
    select * from table1
    if @@rowcount>0
    begin
     waitfor delay '00:00:10' 
     print '不重复读'
     select * from table1
    end第二个连接的结果脏读
    A    B    C
    a1   b1   c
    a2   b2   c
    a3   b3   c'不重复读'
    A    B    C
    a1   b1   c1
    a2   b2   c2
    a3   b3   c3READ COMMITTED指定在读取数据时控制共享锁以避免脏读,但数据可在事务结束前更改,从而产生不可重复读取或幻像数据。该选项是 SQL Server 的默认值。
    在第一个连接中执行以下语句
    SET TRANSACTION ISOLATION LEVEL READ COMMITTED
    begin tran
    print '初始'
    select * from table1
    waitfor delay '00:00:10'  --等待10秒
    print '不重复读'
    select * from table1
    rollback tran
    在第二个连接中执行以下语句
    SET TRANSACTION ISOLATION LEVEL READ COMMITTEDupdate table1 set c='c'
      第一个连接的结果初始
    A    B    C
    a1   b1   c1
    a2   b2   c2
    a3   b3   c3不重复读
    A    B    C
    a1   b1   c
    a2   b2   c
    a3   b3   cREPEATABLE READ锁定查询中使用的所有数据以防止其他用户更新数据,但是其他用户可以将新的幻像行插入数据集,且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别,所以应只在必要时才使用该选项。
    在第一个连接中执行以下语句
    SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
    begin tran
    print '初始'
    select * from table1
    waitfor delay '00:00:10'  --等待10秒
    print '幻像读'
    select * from table1
    rollback tran
    在第二个连接中执行以下语句
    SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
    insert  table1 select 'a4','b4','c4'
    第一个连接的结果初始
    A    B    C
    a1   b1   c1
    a2   b2   c2
    a3   b3   c3幻像读
    A    B    C
    a1   b1   c1
    a2   b2   c2
    a3   b3   c3
    a4   b4   c4
    SERIALIZABLE在数据集上放置一个范围锁,以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。该选项的作用与在事务内所有 SELECT 语句中的所有表上设置 HOLDLOCK 相同。
    在第一个连接中执行以下语句
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    begin tran
    print '初始'
    select * from table1
    waitfor delay '00:00:10'  --等待10秒
    print '没有变化'
    select * from table1
    rollback tran
    在第二个连接中执行以下语句
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    insert  table1 select 'a4','b4','c4'
    第一个连接的结果初始
    A    B    C
    a1   b1   c1
    a2   b2   c2
    a3   b3   c3没有变化
    A    B    C
    a1   b1   c1
    a2   b2   c2
    a3   b3   c3