MYSQL事務篇(高級篇)


 1.事務介紹:

  • 一般是指要做的或所做的事情。 在計算機 術語 中是指訪問並可能更新數據庫中各種 數據項 的一個程序 執行單元 (unit)

2.數據庫事務具有ACID四大特性

  • ACID是以下4個詞的縮寫:
  • 原子性(atomicity) :事務最小工作單元,要么全成功,要么全失敗 。
  • 一致性(consistency): 事務開始和結束后,數據庫的完整性不會被破壞 。
  • 隔離性(isolation) :不同事務之間互不影響,四種隔離級別為RU(讀未提交)、RC(讀已提交)、RR(可重復讀)、SERIALIZABLE (串行化)。
  • 持久性(durability) :事務提交后,對數據的修改是永久性的,即使系統故障也不會丟失 。

3.隔離級別:

  • 四種隔離級別分別為:

  1)未提交讀(READ UNCOMMITTED/RU) 如果一個事務讀到了另一個未提交事務修改過的數據,那么這種 隔離級別 就稱之為 未提交讀 會產生臟讀的情況

  2)   已提交讀(READ COMMITTED/RC) 不可重復讀:一個事務因讀取到另一個事務已提交的update。導致對同一條記錄讀取兩次以上的結果不一致。

  如果一個事務只能讀到另一個已經提交的事務修改過的數據,並且其他事務每對該數據進行一次修改並提交后,該事務都能查詢得到最新值,那么這種 隔離級別 就稱之為 已提交讀,會產生幻讀的情況。

  3)可重復讀(REPEATABLE READ/RR) 在一些業務場景中,一個事務只能讀到另一個已經提交的事務修改過的數據,但是第一次讀過某條記錄后,

  即使其他事務修改了該記錄的值並且提交,該事務之后再讀該條記錄時,讀到的仍是第一次讀到的值,而不是每次都讀到不同的數據。那么這種 隔離級別 就稱之為 可重復讀,會產生幻讀的情況。

  4)串行化(SERIALIZABLE) 最高的默認級別,強制事務串行執行(即一個事務一個事務執行)。效率極其低下。

  幻讀:一個事務因讀取到另一個事務已提交的insert數據或者delete數據。導致對同一張表讀取兩次以上的結果不一致。

  不可重復讀: 一個事務因讀取到另一個事務已提交的update。導致對同一條記錄讀取兩次以上的結果不一致。

4.講講事務和MVCC底層原理詳解:

 比如現在有一個例子:

一個轉賬的一個案例:

丟失更新

兩個事務針對同一數據都發生修改操作時,會存在丟失更新問題。

4.1解決方案:LBCC:

使用LBCCLBCC,基於鎖的並發控制,英文全稱Lock Based Concurrency Control)可以解決上述的
問題。查詢總額事務會對讀取的行加鎖,等到操作結束后再釋放所有行上的鎖。因為用戶A的存款被 鎖,導致轉賬操作被阻塞,直到查詢總額事務提交並將所有鎖都釋放。
示例:這種方案比較簡單粗暴,就是一個事務去讀取一條數據的時候,就上鎖,不允許其他事務來操作
 
 

4.2:解決方案2:MVVC:

MVCCMVCC,多版本的並發控制,英文全稱:Multi Version Concurrency Control)機制可
以解決這個問題。查詢總額事務先讀取了用戶A的賬戶存款,然后轉賬事務會修改用戶A和用戶B賬戶存
款,查詢總額事務讀取用戶B存款時不會讀取轉賬事務修改后的數據,而是讀取本事務開始時的數據副(REPEATABLE READ隔離等級下)
只支持RC,RR隔離級別
 
示例: MVCC 使得數據庫讀不會對數據加鎖,普通的 SELECT 請求不會加鎖,提高了數據庫的並發處理能力

 

5.MysqlMVCC實現(重點):

  • MVCC是用於數據庫提供並發訪問控制的並發控制技術MVCC最大的好處:相信也是耳熟能詳:讀不加鎖,讀寫不沖突。
  • 多版本並發控制僅僅是一種技術概念,並沒有統一的實現標准,
  • 其核心理念就是數據快照,不同的事務訪問不同版本的數據快照,從而實現不同的事務隔離級別。

 

5.1MVVC的實現機制:

mvvc是通過undo log+readview實現的:

undo log:

  • 是一個回滾日志就是提交一些未提交操作的原始狀態 然后它會記錄版本號 :
  • 如果有主鍵是2個隱藏列 如果沒有則是3個隱藏列
  • 隱藏列呢就是三個部分組成
  • 1.rowid:如果沒有主鍵則會自動生產
  • 2.回滾指針:指向記錄的上一個版本號
  • 3.事務id:記錄了操作這條事務的id(這個id是唯一的而且是自增的) 然后每次更新都會有生產一個新版本通過回滾指針指向舊版本 形成一個版本鏈
  • 執行刪除操作的時候是不會直接刪除的是進行了一個打了一個刪除標記,真正刪除是通過purge線程執行清除操作的

ReadView:

  • 相當於一個快照,只要readview不改變則讀取的結果就是一樣的

  • readview生產時刻就是執行select操作時生產的一個select對應一個ReadView select執行完畢那么ReadView就會失效
  • 它就是一個數組(m_ids) 記錄了當前時刻數據庫活躍的事務id列表,它的可見性判斷呢可以根據m_ids與事務id進行判斷 判斷條件可以根據(如果都可讀以最新版本為准):

  

       

句個列子比如:

 

 如果數據庫沒有活躍的事務,那么ReadView(m_ids)中包含的就是將要生成的事務id。

REPEATABLE READ(RR)隔離級別下,MVCC具體是如何操作的。

1.SELECT
InnoDB 會根據以下兩個條件檢查每行記錄:
1. InnoDB只查找版本早於當前事務版本的數據行(也就是,行的事務編號小於或等於當前事務的事 務編號)
 這樣可以確保事務讀取的行,要么是在事務開始前已經存在的,要么是事務自身插入或 者修改過的。
2. 刪除的行要事務ID判斷,讀取到事務開始之前狀態的版本。
只有符合上述兩個條件的記錄,才能返回作為查詢結果。
2.INSERT
InnoDB為新插入的每一行保存當前事務編號作為行版本號。
3.DELETE
InnoDB為刪除的每一行保存當前事務編號作為行刪除標識。
4.UPDATE
InnoDB為插入一行新記錄,保存當前事務編號作為行版本號,同時保存當前事務編號到原來的行作為行刪除標識。

MVCC是如何解決隔離級別的呢?

RC事務隔離級別的實現:

讀已提交:當前事務可以讀取其他事務提交的結果

實現方案:當前事務執行select語句時會生產一個ReadView,如果再次執行這個selct語句繼續生成ReadView。

RR事務隔離級別的實現:

可重復讀:當前事務中執行的select語句的多次執行結果都是相同的,不管其他事務有沒有提交。

實現方案:在當前事務執行select語句生產一個ReadView,之后同一個select使用同一個ReadView

RC和RR的區別:

  • READ COMMITTD REPEATABLE READ 這兩個隔離級別的一個很大不同就是生成 ReadView 的時機不
  • READ COMMITTD 在每一次進行普通 SELECT 操作前都會生成一個 ReadView
  • REPEATABLE READ 只在第一次進行普通 SELECT 操作前生成一個 ReadView ,之后的查詢操作都重復這個 ReadView就好了。
  • REPEATABLE READ隔離級別下,MVCC具體是如何操作的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM