事務的基本要素:(ACID)
原子性(Atomicity):
一個事務不可分割,要么全部執(zhí)行成功,要么全部不執(zhí)行。
一致性(Consistency):
事務執(zhí)行數(shù)據(jù)前后一致。比如A向B轉(zhuǎn)賬,不可能A扣了錢,B卻沒收到。一致性則是通過持久性+原子性+隔離性來保證;
隔離性(Isolation):
一個事務不應該受到其他事務的干擾。在一個事務執(zhí)行過程中,另一個事務不能穿插執(zhí)行,比如A正在從一張銀行卡中取錢,在A取錢的過程結(jié)束前,B不能向這張卡轉(zhuǎn)賬。通過鎖以及 MVCC,使事務相互隔離開。
持久性(Durability):
事務完成后,事務對數(shù)據(jù)庫的所有更新將被保存到數(shù)據(jù)庫,不能回滾。使用 redo log 來實現(xiàn),只要 redo log 日志持久化了,當系統(tǒng)崩潰,即可通過redo log 把數(shù)據(jù)恢復。
事務的隔離級別
臟讀 :
當前事務可以讀到另一個事務未提及的事務
不可重復讀:
當前事務中,同一條sql,多次查詢內(nèi)容不一致(側(cè)重于修改)
幻讀:
當前事務中,同一條sql,多次查詢,結(jié)果條數(shù)不一致(側(cè)重于新增/修改)
讀取未提交的:
臟讀、不可重復讀、幻讀都可能出現(xiàn);
讀取已提交的:
可以解決臟讀問題,不能解決不可重復讀和幻讀問題;
可重復讀:
確保事務可以多次從一個字段中讀取相同的值。在這個事務持續(xù)期間,禁止其他事務對這個字段進行更新??梢员苊馀K讀和不可重復讀,但是幻讀的問題依然存在。
串行化:
確保事務可以從一個表中讀取相同的行,在這個事務持續(xù)期間,禁止其他事務對該表執(zhí)行插入,更新,刪除。所有的并發(fā)問題都能避免,但是性能比較低。
在可重復讀級別下[MVCC]是如何幻讀問題的
MVCC,全稱Multi-Version Concurrency Control,即多版本并發(fā)控制。 在數(shù)據(jù)庫管理系統(tǒng)中,實現(xiàn)對數(shù)據(jù)庫的并發(fā)訪問。
快照讀:
在讀取數(shù)據(jù)時,讀取的是一個靜態(tài)版本(快照)而不是實時的版本。在快照讀期間,即使其他事務修改了數(shù)據(jù),快照讀也不會受到影響。
當前讀:
讀取數(shù)據(jù)時,讀取的是最新的數(shù)據(jù)版本,而不是一個靜態(tài)版本。當前讀會獲取鎖來確保讀取的數(shù)據(jù)是最新的,并且在讀取期間阻塞其他事務對該數(shù)據(jù)的修改。
在MySQL中,除了普通查詢屬于快照讀,其它(比如update、insert、delete)都屬于當前讀。另外,“select ... for update” 這種查詢語句也是當前讀,每次執(zhí)行的時候都是讀取最新的數(shù)據(jù)。
innoDB解決普通查詢的幻讀問題
innoDB就是根據(jù)不同的快照策略+undolog實現(xiàn)不同的隔離級別的。簡單來說,就是當一個事務第一次對數(shù)據(jù)庫就是查詢時,會創(chuàng)建一個Read View,在同個事務中,后續(xù)的查詢語句都會利用這個Read View在undo log版本鏈中找到開始時的數(shù)據(jù),這樣同個事務中多次查詢讀取到的數(shù)據(jù)結(jié)果就是一樣的了。
innoDB當前讀如何解決幻讀問題
間隙鎖:
間隙鎖是指鎖定一個數(shù)據(jù)范圍,但是不包括這個范圍內(nèi)的任何數(shù)據(jù)。間隙鎖的目的是為了防止其他事務在這個范圍內(nèi)插入新的數(shù)據(jù),從而保證事務的隔離性。
記錄鎖:
記錄鎖是指鎖定數(shù)據(jù)庫中的一條記錄,以防止其他事務對這條記錄進行修改或刪除。在關系型數(shù)據(jù)庫中,記錄鎖通??梢苑譃榕潘i和共享鎖兩種類型。
當使用當前讀查詢數(shù)據(jù)時,會獲取共享鎖或排他鎖,以防止其他事務修改或刪除該行數(shù)據(jù)。
可重復讀級別下的幻讀問題
產(chǎn)生幻讀的場景
1、同一事務第二次查詢前對數(shù)據(jù)進行了更新操作
2、同一事務第一次使用快照讀第二次使用當前讀
如何避免幻讀
①盡量避免對空數(shù)據(jù)進行更新;
②在開啟事務后馬上執(zhí)行select ... for update 當前讀操作,這樣它就會對記錄加上next-key lock,避免其它事務對范圍內(nèi)數(shù)據(jù)的修改。
由上可得,MySQL的“可重復讀”級別并沒有徹底避免幻讀問題,在個別極端情況下仍會出現(xiàn)幻讀。了解了可能出現(xiàn)幻讀的場景,在實際應用中才能更好的規(guī)避該問題。同時,在不同需求下選擇不同的事務隔離級別可以更好地發(fā)揮性能和節(jié)省資源。