在後端開發中咱們不可避免的會碰見MySQL數據併發更新的狀況,做爲一名後端研發,如何解決這類問題也是必需要知道的,同時這也是面試中常常考察的知識點。html
SQL語句爲以下時,是否會加鎖?node
UPDATE table1 SET num = num + 1 WHERE id=1;複製代碼
答案是不會git
實際上MySQL是支持給數據行加鎖(InnoDB)的,而且在UPDATE/DELETE等操做時確實會自動加上排它鎖。只是並不是只要有UPDATE關鍵字就會全程加鎖,針對上面的MySQL語句而言,其實並不僅是一條UPDATE語句,而應該相似於兩條SQL語句(僞代碼):github
a = SELECT * FROM table1 WHERE id=1;
UPDATE table1 SET num = a.num + 1 WHERE id=1; 複製代碼
其中執行SELECT語句時沒有加鎖,只有在執行UPDATE時才進行加鎖的。因此纔會出現併發操做時的更新數據不一致。緣由找到了,解決問題就不遠了。而針對這類問題,解決的方法能夠有2種:面試
SELECT ... LOCK IN SHARE MODE #共享鎖,其它事務可讀,不可更新
SELECT ... FOR UPDATE #排它鎖,其它事務不可讀寫複製代碼
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
對 for update上鎖進行一次實踐數據庫
一個student表,其中有一條數據後端
開啓兩個client
併發
select name from student where id = 1 for update;複製代碼
總的來講,這2種方式均可以支持數據庫的併發更新操做。但具體使用哪種就得看實際的應用場景,應用場景對哪一種支持更好,而且對性能的影響最小。性能
參考自: