使用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


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM