併發操作會帶來一系列的問題
更新丟失(lost update)
當兩個或多個事務選擇了同一行然後基於最初選定的值更新改行時,由於每個事務都不知道其他事務的存在,就會發生丟失更新的問題,最後更新覆蓋了由其他事務所做的更新
髒讀 (dirty reads)
乙個事務正在對一條記錄做修改,在這個事務完成並提交前,這條記錄的資料就處於不一致的狀態;這時,另乙個事務也讀取同一條基礎,如果不加控制,第二個事務讀取這些"髒"資料,並據此作進一步的處理,就會產生未提交的資料的依賴關係,這種叫做"髒讀"
不可重複讀(non-repeatable reads)
乙個事務在讀取某些資料的某個時間,再次讀取以前讀過的資料,卻發現其讀出的資料已經發生改變,或者某些記錄被刪除了!! 這就叫不可重複讀
(不符合隔離性)
幻讀乙個事務按相同的查詢條件讀取以前檢索過的資料,卻發現其他事務插入了滿足其查詢條件的新資料
,這種現象叫做"幻讀",好像重來沒出現過
設定了 mysql 事務隔離級別, mysql對於操作同一行資料會自動加鎖
對於可重複讀, mysql使用的是 mvcc 機制 ,multi version concurrent control,多版本併發控制機制
select 操作不會更新版本,每次查詢都會做一次快照,用的是快照版本。然後修改後,真實資料以及和快照版本不一致了,但是 mysql為了讓邏輯準確,更新的時候會那資料庫最新的資料進行更新,而讀是讀的快照版本的資料。
商品超賣,就是這種原因。
這種就是當前讀和快照讀的區別
快照讀會讓效能高一點。所以 select 出來再 update 會有 bug
注意點:sql應該這樣寫: update account set balance = balance-50 where id = 1;
可重複讀的話,select不會更新版本好,是快照讀(歷史版本),而insert 、update和delete 會更新版本好,是當前讀(當前版本)
所以更新之後再開查就可能會有幻讀的現象:
session1: select * from account;
session2: insert into account (name,money) values('ss',100);
session1: update account set name = 'lyr' where id = 1 ;
session1: select * from account;
如果 session1: 沒有update account 這張表,會用快照讀,不會出現幻讀的問題
然而: session1: update 了 account這張表,那麼就會從快照讀改當前讀
而session2 這個時候 插入了一條 name='ss', money=100 的資料
session1 再來查表,發現無緣無故有多了一條,這個就像幻覺一樣的資料(幽靈般的出現了)
這個就是幻讀
改成 序列化,那就什麼問題也沒有了,但是不應該這樣,因為效率低
mysql 使用可重複讀 兼顧了效率盡量的解決了髒讀和不可重複讀的問題
檢視mysql近期死鎖的日誌資訊:
show engine innodb status\g
mysql的優化:
盡可能讓所有資料檢索通過索引完成,避免無索引行鎖公升級為表鎖
合理設計索引,盡量縮小鎖的範圍
盡可能檢索檢索條件,避免間隙鎖
盡量控制事務大小,減少鎖定資源量和時間長度
盡可能低階別的事務隔離
這樣就可以解決併發問題了
update account set money = money-1 where id='llyr' and money >0;
mysql可以使用乙個間隙鎖,只要是範圍的話 mysql自動加鎖,一般不會有幻讀問題
條件 是乙個範圍,mysql就加鎖了
這樣可以解決幻讀問題
還有其他的鎖,比如 for update 獨佔鎖之類的
mysql 開啟事務的時候 update語句的時候加鎖,commit後釋放
所以sql 寫的好,一般不會有問題。
資料庫的併發問題
a事務讀取了b事務尚未提交的更改資料,並且在這個資料基礎上進行操作。如果此時恰巧b事務進行回滾,那麼a事務讀到的資料是根本不被承認的。以下是乙個取款事務和轉賬事務併發時引起的髒讀場景。時間轉賬事務a 取款事務b t1開始事務 t2開始事務 t3查詢賬戶餘額為1000元 t4取出500元,把餘額改為5...
資料庫併發下的髒資料問題
事情是這樣的,我有個需求,簡單來說是每次insert三條記錄,每次都給本次insert的記錄version 1,理想情況下,假設沒有併發,最後的資料應該是這樣 id name version 1 name 1 2 name 1 3 name 1 4 name 2 5 name 2 6 name 2 ...
資料庫併發操作帶來的問題
1 丟失更新 當兩個或多個事物讀入同一資料並修改,會發生丟失更新問題,即後乙個事物更新的結果被前一事務所做更新覆蓋 即當事務a和b同事進行時,事務a對資料已經改變但並未提交時b又對同一資料進行了修改 注意此時資料是a還未提交改變的資料 到時a做的資料改動丟失了 2 不可重複讀 當兩個資料讀取某個資料...