zoukankan      html  css  js  c++  java
  • 为什么NOLOCK查询提示是个不明智的想法

    一些人总当NOLOCK查询提示是SQL Server里的加速器,因为它避免了大量的死锁情景。在这篇文章里,我想向你展示下为什么NOLOCK查询提示是个不好的想法。

    脏读(Dirty Reads) 

    NOLOCK查询提示一个最大的副作用就是在你的记录集会出现所谓的脏读这个事实。我们来看下面的代码:

    1 BEGIN TRANSACTION
    2 
    3 UPDATE Person.Person
    4     SET FirstName = 'James'
    5 WHERE LastName = 'Jones'

    如你所见,我开始了一个新的事务,对AdventureWorks2012数据库里的Person.Person表进行UPDATE语句。现在当你尝试同时在另一个会话里读取这个记录时,这个SELECT语句会阻塞——在这个情况下请求的共享锁(S)会被已经授予的排它锁(X)阻塞——写阻塞读操作。 

    1 SELECT
    2     FirstName,
    3     LastName
    4 FROM Person.Person
    5 WHERE LastName = 'Jones'
    6 GO

    一些人现在回应用SQL Server里的加速器,使用NOLOCK查询提示: 

    1 SELECT
    2     FirstName,
    3     LastName
    4 FROM Person.Person WITH (NOLOCK) -- It's a kind of magic...
    5 WHERE LastName = 'Jones'
    6 GO

    如你所见死锁情景马上解决了,你从SQL Server返回记录了——遗憾的是在你面前现在有脏读(Dirty Read):你读取了尚未提交的数据。假设现在用UPDATE语句的第1个事务回滚了:在这个情况下,你已读取的数据在SQL Server里逻辑上是从未存在的。

     

    因此NOLOCK查询提示并不是在每个情景都是有用的。 如果你想运行一个报表,或者你只想快速返回结果,记录不用100%正确,这“可以是”个可取的(考虑下一天的平均销售额)。当然,当你需要精确的结果,NOLOCK并不可取。当然也有一些特定场景即使NOLOCK也会阻塞

    读提交快照隔离(Read Committed Snapshot Isolation (RCSI))

    有人给我提了为什么NOLOCK查询提示基本是一个不方便的(no-go)的选择:你不能在明显的方式里切换你的数据库查询到读提交快照隔离(Read Committed Snapshot Isolation (RCSI))。我从未想过这个情景,但没错是对的。读提交快照隔离(Read Committed Snapshot Isolation (RCSI))是个数据库选项。当你启用它的时候,每个查询都是在新的读提交快照乐观隔离级别里——只要在你的事务里不指定任何隔离级别。

    对于特定的SQL语句使用NOLOCK查询提示,你临时修改隔离级别为未提交读(Read Uncommitted)。因此SQL语句也不会从读提交快照隔离受益,因为语句并没有在默认的提交读( Read Committed)隔离运行。这就对了!当你下次写下神奇的……WITH(NOLOCK)……时,好好想下这个额外参数。

    小结

    使用NOLOCK查询提示运行每个查询并不都有意义。一方面你会通过脏读(Dirty Reads)返回不一致的数据。另一方面你不能从读提交快照隔离(Read Committed Snapshot Isolation (RCSI))乐观隔离级别里受益,因为你临时修改了你SQL语句的默认隔离级别。

    感谢关注! 

    参考文章:

    https://www.sqlpassion.at/archive/2015/06/15/why-the-query-hint-nolock-is-a-bad-idea/

  • 相关阅读:
    为了实现一个函数 clone ,可以对 JavaScript 中 5 种主要的数据类型 (包括 Number、 St「ing 、 Object、 A「「ay、 Boolean )进行值(深)复制。
    说说你对语义化的理解
    vue 根据字符串的长度控制显示的字数超出显示省略号
    加密号码将中间四位改为*
    前端项目部署错误:npm ERR! notarget No matching version found for event-stream@3.3.6
    npm报错:A complete log of this run can be fund in:........
    nrm插件的安装插件和使用
    Vue过渡搭配Velocity.js动画的基本使用
    Asp.Net Core&钉钉开发系列
    KnockoutJS知识规整目录
  • 原文地址:https://www.cnblogs.com/woodytu/p/4748756.html
Copyright © 2011-2022 走看看