MySQL並發更新數據時的處理方法


     執行SELECT語句時沒有加鎖,只有在執行UPDATE時才進行加鎖的。所以才會出現並發操作時的更新數據不一致

a = SELECT * FROM table1 WHERE id=1;
UPDATE table1 SET num = a.num + 1 WHERE id=1; 

  解決的方法可以有2種:

通過事務顯式的對SELECT進行加鎖
使用樂觀鎖機制

  對SELECT進行加鎖的方式有兩種,如下:

SELECT ... LOCK IN SHARE MODE       #共享鎖,其它事務可讀,不可更新
SELECT ... FOR UPDATE               #排它鎖,其它事務不可讀寫

  默認情況下SELECT語句是不會加鎖的。並且對於上面提到的場景,必須使用排它鎖。另外,上面的2種語句只有在事務之中才能生效,否則不會生效。在MySQL命令行使用事務的方式如下:

SET AUTOCOMMIT=0; 
BEGIN WORK; 
    a = SELECT num FROM table1 WHERE id=2 FOR UPDATE;  
    UPDATE table1 SET num = a.num + 1 WHERE id=2; 
COMMIT WORK;

  只要以后更新數據時,都使用這樣事務來進行操作;那么在並發的情況下,后執行的事務就會被堵塞,直到當前事務執行完成。(通過鎖把並發改成了順序執行)

樂觀鎖

  在具體更新數據的時候更新條件中會添加版本號信息,

  • 當版本號沒有變化的時候說明該數據行未被更新過,並且也滿足更新條件,所以會更新成功。
  • 當版本號有變化的時候,則無法更新數據行,因為條件不滿足,此時就需要在進行一次SQL操作。(重新查詢記數據行,再次使用新的版本號更新數據)
  


免責聲明!

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



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