丟失更新:兩個使用者(或以上)對同乙個資料物件操作引起的資料丟失。
解決方案:1.悲觀鎖,假設丟失更新一定存在;sql後面加上for update;這是資料庫的一種機制。
2.樂觀鎖,假設丟失更新不一定發生。update時候存在版本,更新時候按版本號進行更新。
樂觀鎖不是資料庫自帶的,需要我們自己去實現。樂觀鎖是指運算元據庫時(更新操作),想法很樂觀,認為這次的操作不會導致衝突,在運算元據時,並不進行任何其他的特殊處理(也就是不加鎖),而在進行更新後,再去判斷是否有衝突了。
通常實現是這樣的:在表中的資料進行操作時(更新),先給資料表加乙個版本(version)字段,每操作一次,將那條記錄的版本號加1。也就是先查詢出那條記錄,獲取出version欄位,如果要對那條記錄進行操作(更新),則先判斷此刻version的值是否與剛剛查詢出來時的version的值相等,如果相等,則說明這段期間,沒有其他程式對其進行操作,則可以執行更新,將version欄位的值加1;如果更新時發現此刻的version值與剛剛獲取出來的version的值不相等,則說明這段期間已經有其他程式對其進行操作了,則不進行更新操作。
實現:下單操作包括3步驟:
1.查詢出商品資訊除了自己手動實現樂觀鎖之外,現在網上許多框架已經封裝好了樂觀鎖的實現,如hibernate,需要時,可能自行搜尋"hiberate 樂觀鎖"試試看。select (status,status,version)
from t_goods where id=#
2.根據商品資訊生成訂單
3.修改商品status為2
update t_goods
set status=2,version=version+1where id=#
and version=#;
通過時間戳方式:
例如:有這樣乙個表:
每次更新時update在條件後再附加乙個時間為條件:
update user_info set password='與樂觀鎖相對應的就是悲觀鎖了。悲觀鎖就是在運算元據時,認為此操作會出現資料衝突,所以在進行每次操作時都要通過獲取鎖才能進行對相同資料的操作,這點跟j**a中的synchronized很相似,所以悲觀鎖需要耗費較多的時間。另外與樂觀鎖相對應的,悲觀鎖是由資料庫自己實現了的,要用的時候,我們直接呼叫資料庫的相關語句就可以了。somelog
' where username='
somelog
'and time='
2018-07-11
';
說到這裡,由悲觀鎖涉及到的另外兩個鎖概念就出來了,它們就是共享鎖與排它鎖。共享鎖和排它鎖是悲觀鎖的不同的實現,它倆都屬於悲觀鎖的範疇。
悲觀鎖分為兩種:共享鎖和排它鎖sql寫法共享鎖是其它事務可以讀但是不能寫
排他鎖是只有自己得事務有許可權對此資料進行讀寫
共享鎖(s):
select * from table_name where ... lock in share mode;排他鎖(x):
select * from table_name where ... for update;加鎖必須先開啟事務:begin;(開啟事務)->加鎖、操作->commit;(提交事務,歸還鎖)
mysql悲觀鎖和樂觀鎖
mysql鎖機制分為表級鎖和行級鎖,本文就和大家分享一下我對mysql中行級鎖中的共享鎖與排他鎖進行分享交流。共享鎖又稱為讀鎖,簡稱s鎖,顧名思義,共享鎖就是多個事務對於同一資料可以共享一把鎖,都能訪問到資料,但是只能讀不能修改。排他鎖又稱為寫鎖,簡稱x鎖,顧名思義,排他鎖就是不能與其他所並存,如乙...
MySQL悲觀鎖和樂觀鎖
引言 之所以叫做悲觀鎖,是因為這是一種對資料的修改抱有悲觀態度的併發控制方式。我們一般認為資料被併發修改的概率比較大,所以需要在修改之前先加鎖。例子 0.開始事務 begin 1.查詢出商品庫存資訊 select quantity from items where id 1 for update 2...
悲觀鎖和樂觀鎖
1.悲觀鎖,正如其名,它指的是對資料被外界 包括本系統當前的其他事務,以及來自外部系統的事務處理 修改持保守態度,因此,在整個資料處理過程中,將資料處於鎖定狀態。悲觀鎖的實現,往往依靠資料庫提供的鎖機制 也只有資料庫層提供的鎖機制才能真正保證資料訪問的排他性,否則,即使在本系統中實現了加鎖機制,也無...