zoukankan      html  css  js  c++  java
  • 使用Sqlserver更新锁防止数据脏读

      有时候我们需要控制某条记录在程序读取后就不再进行更新,直到事务执行完释放后才可以。这时候我们就可以将所有要操作当前记录的查询加上更新锁,以防止查询后被其它事务修改。这种操作只锁定表中某行而不会锁定整个表,体验更好。

      测试sql代码如下:

      在一个查询中执行如下语句

    begin tran
     SELECT InvestState FROM InvestOrdersABC WITH (UPDLOCK) where id=10005
     waitfor delay '00:00:10' 
     update InvestOrdersABC set InvestState='2' where id=10005
    commit tran

      1、在另外的一个查询中执行以下语句

    SELECT InvestState FROM InvestOrdersABC  where id=10005

      发现在第一个事务执行完以前查到的数值还是原来的数值0,直到更新完成后才会变成2,如果加上锁,代码如下:

    SELECT InvestState FROM InvestOrdersABC WITH (UPDLOCK) where id=10005

      发现sql语句必须等到第一个连接里的事务完成才执行完成,这是因为这个sql的连接的更新锁认为第一个事务里的更新锁可能会对数据进行修改,因此必须等事务执行完成才执行。此时更新锁变为排他锁。

      2、如果执行更新操作:

    begin tran
     update InvestOrders set InvestState='3' where id=10005
    commit tran

       发现无法更改,只能等到第一个查询完成后才会进行修改。其实和加锁不加锁已经没什么关系,为什么呢?因为SQL Server在执行INSERT、 UPDATE 或DELETE 命令时,会自动使用独占锁。

      3、上文的事务未加隔离级别,事务的默认隔离级别为READ  committed,不加锁因此在第1点里还可以进行查询。当数据库事务的隔离级别为REPEATABLE READ,SERIALIZABLE时,如果查询需要加共享锁:

    SELECT InvestState FROM InvestOrdersABC WITH (HoldLOCK) where id=10005


     

  • 相关阅读:
    2020-3-23学习地图
    HashMap<K,V>类
    2020-3-21学习地图
    模板模式
    2020-3-20学习地图
    字符串常量池String Constant Pool
    2020-3-19学习地图
    2020-3-18学习地图
    MySQL游标
    2020-3-16学习地图
  • 原文地址:https://www.cnblogs.com/silent2012/p/5169566.html
Copyright © 2011-2022 走看看