zoukankan      html  css  js  c++  java
  • SQL Server 的事务和锁(一)

    最近在项目中进行压力测试遇到了数据库的死锁问题,简言之,如下的代码在 SERIALIZABLE 隔离级别造成了死锁:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT @findCount=COUNT(id) FROM MyTable
    WHERE [fk_related_id]=@Argument
     
    IF (@findCount > 0)
    BEGIN
        ROLLBACK TRANSACTION
        RETURN ERROR_CODE
    END
     
    INSERT INTO MyTable ([fk_related_id],…)
    VALUES (@Argument,…)
     
    COMMIT TRANSACTION
    RETURN SUCCESS_CODE

    在搞清楚这个问题的过程中做了不少的实验,与各位共享。这一篇是开篇,主要说明的是 SQL Server 的四种(其实还有别的)经典的事务隔离级别,以及在不同的隔离级别下锁的使用手段,以及所带来的不同的数据一致性。

    SQL Server 中锁的种类(Schema操作就暂时不涉及了)

    锁类型 描述
    (Shared Lock) 用于只读操作数据锁定
    (Update Lock) 用于数据的更新,在数据真正的需要更新的时候会申请升级为X锁。
    X(Exclusive Lock) 独占锁,用于数据的更改。
    Key-Range Lock(稍后讨论) 仅仅在 Serializable 隔离级别保护数据,以避免任何有可能使得本事务第二次读取信息产生错误的数据插入操作

    各个事务隔离级别下锁的使用

    SQL Server 中有四种事务隔离级别,具体的大家去参建 MSDN。下面列出在不同的事务隔离级别下这些锁是如何使用的:

    隔离级别 读数据锁状态 写数据锁状态 锁持有时间
    Read Uncommitted 不获得任何锁 不获得任何锁  
    Read Committed 数据获得S锁 对于 INSERT、DELETE、UPDATE的执行,获得X锁;对于UPDATE的标记,获得U锁; 读完即释放,并不持有至事务结束。
    Repeatable Read 数据获得S锁 对于 INSERT、DELETE、UPDATE的执行,获得X锁;对于UPDATE的标记,获得U锁; 持有至事务结束
    Serializable 数据获得S锁,同时获得Key-Range锁。 对于 INSERT、DELETE、UPDATE的执行,获得X锁;对于UPDATE的标记,获得U锁,同时获得Key-Range锁。 持有至事务结束

    我们可以利用这些知识形象说明各个隔离级别下的数据一致性:

    Read Uncommitted 级别

    (1)脏读

    image

    (2)更新丢失

    image

    (3)不可重复读

    image

    (4)幻读

    clip_image001

    Read Committed 级别

    (1)脏读

    clip_image001[5]

    (2)更新丢失

    clip_image002

    (3)不可重复读

    clip_image003

    (4)幻读

    clip_image004

    Repeatable Read 级别

    (1)脏读

    clip_image005

    (2)更新丢失

    clip_image006

    (3)不可重复读

    clip_image007

    (4)幻读

    clip_image008

    Serializable 级别

    (1)脏读

    clip_image009

    (2)更新丢失

    clip_image010

    (3)不可重复读

    clip_image011

    (4)幻读

    clip_image012

    我们从上图可以比较直观的看到以下的结论

      脏读 更新丢失 不可重复读 幻读
    Read Uncommitted 可能 可能 可能 可能
    Read Committed 不可能 可能 可能 可能
    Repeatable Read 不可能 不可能 不可能 可能
    Serializable 不可能 不可能 不可能 不可能

    这一篇到此为止,下一篇详细介绍 Key-Range Lock 并分析开篇提到的死锁问题。

  • 相关阅读:
    P1886 滑动窗口 单调队列
    用三维的视角理解二维世界:完美解释meshgrid函数,三维曲面,等高线,看完你就懂了。...
    用三维的视角理解二维世界:完美解释meshgrid函数,三维曲面,等高线,看完你就懂了。...
    SaltStack入门
    编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
    time模块中time.time与time.sleep
    【函数篇】装饰器
    【函数篇】函数的进阶,名称空间、作用域、函数的嵌套、作用域链
    闭包!!!
    默认参数的陷阱
  • 原文地址:https://www.cnblogs.com/lenther2002/p/4488382.html
Copyright © 2011-2022 走看看