1、InnoDB行鎖是通過給索引上的索引項加鎖來實現的,只有通過索引條件檢索數據,InnoDB才使用行級鎖,否則,InnoDB將使用表鎖。
2、由於MySQL的行鎖是針對索引加的鎖,不是針對記錄加的鎖,所以雖然是訪問不同行的記錄,但是如果是使用相同的索引鍵,是會出現鎖衝突的。應用設計的時候要注意這一點。
3、當表有多個索引的時候,不同的事務可以使用不同的索引鎖定不同的行,另外,不論是使用主鍵索引、唯一索引或普通索引,InnoDB都會使用行鎖來對數據加鎖。
4、即便在條件中使用了索引字段,但是否使用索引來檢索數據是由MySQL通過判斷不同執行計劃的代價來決定的,如果MySQL認爲全表掃描效率更高,比如對一些很小的表,它就不會使用索引,這種情況下InnoDB將使用表鎖,而不是行鎖。因此,在分析鎖衝突時,別忘了檢查SQL的執行計劃,以確認是否真正使用了索引。
5、檢索值的數據類型與索引字段不同,雖然MySQL能夠進行數據類型轉換,但卻不會使用索引,從而導致InnoDB使用表鎖。通過用explain檢查兩條SQL的執行計劃,我們可以清楚地看到了這一點。
樂觀鎖
樂觀鎖不是數據庫自帶的,需要我們自己去實現。樂觀鎖是指操作數據庫時(更新操作),想法很樂觀,認爲這次的操作不會導致衝突,在操作數據時,並不進行任何其他的特殊處理(也就是不加鎖),而在進行更新後,再去判斷是否有衝突了。
1.查詢出商品信息
select (status,status,version) from t_goods where id=#{id}
2.根據商品信息生成訂單
3.修改商品status爲2
update t_goods
set status=2,version=version+1
where id=#{id} and version=#{version};
悲觀鎖:共享鎖與排它鎖
悲觀鎖就是在操作數據時,認爲此操作會出現數據衝突,所以在進行每次操作時都要通過獲取鎖才能進行對相同數據的操作
共享鎖(S鎖)又稱爲讀鎖,若事務T對A加上S鎖,則事務T只能讀A;其他事務只能再對A加S鎖,而不能加排他鎖(X鎖),直到T釋放A上的S鎖。這就保證了其他事務可以讀A,但在T釋放A上的S鎖之前不能對A做任何修改。
排他鎖(X鎖):如果事務T對數據A加上排他鎖後,則其他事務不能再對A加任任何類型的封鎖。獲准排他鎖的事務既能讀數據,又能修改數據。
mysql中select * from xx where id =1 lock in share mode即可給該數據加共享鎖,在該事務提交之前,不允許其他事務進行修改。
(ps:對於update,insert,delete語句會自動加排它鎖)。
添加排它鎖與添加共享鎖類似,執行語句添加 “ for update” 即可。