zoukankan      html  css  js  c++  java
  • SQL Server2005 事务隔离级别

    任何事务无论其隔离级别如何,都具有原子性。原子性和隔离级别是两码事。
    假定只有一种资源数据表上的“行“可以被锁定。锁只有共享锁和排他锁两种。
    锁的兼容性:
      SX
    S 10
    X 00

    事务的隔离级别:
    Read Uncommitted
    数据读取时不需要锁定
    Read Committed
    数据读取时需要共享锁定
    Repeatable Read
    数据读取时需要排他锁
    Serializable
    事务必须等同于串行执行

    注意无论任何时候更新行都必须要有排他锁。
    插入行不需要锁。
    在Read Committed隔离级别下,数据读取完毕后立即释放共享锁,而在Repeatable Read隔离级别下,事务保持共享

    锁直到整个事务结束。

    在SQL Server中调整事务隔离级别是针对会话的,set tran isolation level后,会话中后来开始的事务都在此隔

    离级别上执行。一个事务只能具有一个隔离级别。同一会话中的所有事务必须串行执行。必须通过begin tran语句来覆盖默认事务范围。

    测试:

     /*环境*/

    CREATE TABLE [dbo].[TranTest](
     [Id] [int] IDENTITY(1,1) NOT NULL,
     [count1] [int] NULL,
     [count2] [int] NULL
    )

    insert into TranTest values(1,2)
    insert into TranTest values(3,4)
    insert into TranTest values(5,6)
    insert into TranTest values(7,8)

    约定总是先执行session1,并且在session1结束前执行session2
    1. 排他锁总是在事务结束时释放

    --session 1

    set tran isolation level any
    begin tran
     update TranTest set count1=count1 + 10 where id=1
     waitfor delay '00:00:10'
    commit tran


    --session 2

     select * from TranTest

    现象:session2被阻塞直到session1中的会话结束。

    解释:session1首先执行,更新id=1的行时持有了该行的排他锁,该锁直到session1中的事务结束时释放,这阻止

    了session2获得共享锁。


    2. 读未提交无需任何锁

    --session 1

    set tran isolation level any
    begin tran
     update TranTest set count1=count1 + 10 where id=1
     waitfor delay '00:00:10'
    commit tran

    --session 2

    set tran isolation level read uncommitted
    begin tran
     select * from TranTest
    commit tran

    现象:session2未被阻塞,而是读取到了session1尚未提交的数据。
    解释:读未提交无需锁定,因而绕开了锁定机制。


    3. 死锁

    --session 1

    set tran isolation level read committed
    begin tran
     update TranTest set count1=1000 where id=1
     waitfor delay '00:00:10'
     update TranTest set count1=1000 where id=2
    commit tran

    --session 2

    set tran isolation level read committed
    begin tran
     update TranTest set count1=2000 where id=2
     waitfor delay '00:00:10'
     update TranTest set count1=2000 where id=1
    commit tran

    现象:发生死锁,有一个事务被强制终止。
    解释:session1持有了id=1的行的排他锁,等待id=2的行的排他锁;session2持有了id=2的行的排他锁,等待id=1

    的行排他锁。从逻辑上说这样是会造成死锁的,但实际上在sql server中这种情况也很有可能不会导致死锁。这

    是sql server死锁检测程序的功劳。当它预测到死锁可能发生的时候,可能会悬挂一个事务,等待另一个执行完成

     如果是运行在repeatable read隔离级别下,共享锁会在读取行之后保持。如果读取的行是连接而来的,则锁定参与连接的各个表中对应的行。查询中的子查询中参与的行也会一并被锁定。

    --------------------------------------------------

    最后关于新实现的快照隔离级别和基于行版本控制的read committed。没有实际使用过,不过根据MSDN上的描述,原理应该是这样的:

    在ReadCommitted隔离级别下读取数据不加共享锁。如果被读取的行没有被其他事务修改,那么这一行就是已经提交的行;如果被读取的数据被加了排他锁,则根据行上的链接找到该行的前一版本。这个行上的链接是这么回事,如果一个事务想在一个行上加排他锁,则它必须把这一行的数据copy到tempdb一份,然后在再上做一个到这个前一版本的链接。之后加排他锁的事务才可以尽情的修改原来的行。当提交的时候在把新的行版本插入到版本链中。

    snapshot隔离级别是可重复读的。

    当读取一个行的时候并不用加共享锁,而是读取行在本事务开始之前的版本。

  • 相关阅读:
    【转】Selenium模拟JQuery滑动解锁
    【转】nose-parameterized是Python单元测试框架实现参数化的扩展
    【转】Chrome headless 模式
    RobotFramework:App九宫格滑动解锁
    appium九宫格解锁错误提示:The coordinates provided to an interactions operation are invalid解决办法
    RobotFramework:App滑动屏幕
    robotframework:appium切换webview后,在webview里滑动屏幕
    robotframework:appium切换webview后,在第一个页面操作成功,跳转到第二个页面后,执行命令失败
    robotframework之APP混合H5自动化测试
    Allure生成测试报告
  • 原文地址:https://www.cnblogs.com/smallfa/p/1663752.html
Copyright © 2011-2022 走看看