什么是mysql事物定义_Mysql事务原理
1. 什么是數據庫事務
1.1 事務的應用場景
電商平臺中例如常見的下單流程,會同時操作訂單表,庫存表等,有時候這些操作要在一個事務里面完成。還有金融系統業務的銀行轉賬,需要保證一個賬戶增加另一個賬戶減少,這兩個動作 一定是成功或者同時失敗的。
1.2 事務的定義
維基百科定義:數據庫事務(簡稱:事務)是數據庫管理系統執行過程中的一個邏輯單位,由一個有限的數據庫操作序列構成。
1.3 哪些存儲引擎支持數據庫事務
InnoDB
1.4 事務的四大特性
原子性(Automicity)
我們對數據庫的一系列操作要么都成功要么都失敗,如果其中有哪一步出現就需要回滾。undo log就是實現這一操作,里面記錄了數據修改之前的值(邏輯日志),一旦發現異常就可以使用undo log實現回滾
一致性(Consistency)
事務前后的操作都是合法的正確狀態,例如轉賬,轉賬前和轉賬后金額保持一致,能量守恒狀態。
隔離性 (Isolation)
多個事務操作同一張表或者同一行數據,互不干擾。
持久性 (Durability)
對數據的操作,只要提交成功了,那么結果就是永久的,不會因為系統宕機或者重啟數據庫導致恢復到原來的狀態。其使用redo log來實現,在操作數據時候會寫到內存buffer pool在記錄到redo log,如果刷新到磁盤異常,重啟之后就重新讀取redo log的內容,寫入磁盤。
原子性,隔離性,持久性,最后都是為了實現一致性。
1.5 并發帶來的問題
臟讀
現在有兩個事務,事務A查詢id=1的數據,返回 name為張三。這是事務B開啟事務事務,修改id = 1的name為李四,這時候事務A中再次讀取id =1的數據,得到name =李四,然而事務B并未提交事務,這時候若是B事務回滾,那么A事務得到的就是臟數據。
2. 不可重復讀
同樣是兩個事務,事務A查詢到id=1的數據,返回name為張三
,這是事務B對id =1的數據進行修改,name改成李四,然后提交事務,這時候事務A再次讀id= 1的數據,此時的name也變為李四。這種在一個事務多次讀取同一數據,由于其他事務修改數據造成前后不一致的問題叫做不可重復讀
3. 幻讀
事務A對age>18的數據進行查找,只發現了一條,這時候事務B插入了一條年齡等于30的數據,事務A里面又執行了一次范圍查詢,結果發現多處一條數據。這種在一個事務里面多次執行查詢操作,由于其他事務插入數據造成的前后數據不一致的問題,被叫做幻讀取
不可重復讀的和幻讀很容易混淆,不可重復讀側重于修改,幻讀側重于新增或刪除。解決不可重復讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表
1.6 隔離級別及解決的問題
2. 并發事務解決方案
臟讀、不可重復讀和幻讀都是數據庫讀一致性問題,需要由數據庫提供一定的事務隔離機制來解決。
2.1 LBCC (Lock Based Concurrency Control)
基于鎖的并發控制,在讀取數據的時候對數據進行鎖定,不允許其他事務修改。
2.2 MVCC (Multi Version Concurrency Control)
多版本并發控制,在修改數據的時候,給它建立一個快照,后面的事務來的時候就讀取這個快照。
InnoDB為每行記錄除了提供ROWID外還提供了兩個隱藏字段:
DB_TRX_ID,6個字節:插入或更新行的事務ID,事務編號是自動遞增的(我們把它理解為創建版本號,在數據新增或者修改為新數據的時候,記錄當前事務 ID)
DB_ROLL_PTR,7字節:每次對某條聚簇索引記錄進行改動時,都會把舊的版本寫入到undo日志中,然后這個隱藏列就相當于一個指針,可以通過它來找到該記錄修改前的信息(我們把它理解為刪除版本號,數據被刪除或記錄為舊數據的時候,記錄當前事務 ID
undo log:每次對記錄進行更新后,都會將舊值放在一個undo日志中,隨著更新次數增多,所有版本都會被roll_point屬性連接成一個鏈表,我們稱之為版本鏈,版本鏈的頭結點就是當前記錄的新值。另外,每個版本中還包含生成該版本時事務id
ReadView:出現在RC和RR隔離級別下,RC下,每次讀取都會生成ReadView,RR只會讀取一次,它用于記錄當前事務版本,活躍在系統讀寫的事務等
下面我們通過一個示例來了解MVCC
首先第一個事務初始化數據
begin
insert into test values('1', '張三')
insert into test values('2', '李四')
commit
復制代碼
創建版本是當前事務id,刪除版本為空
idname創建版本刪除版本1張三1undefined
2李四1undefined
第二個事務,執行第1次查詢,讀取到兩條原始數據,這個時候事務 ID 是 2:
begin;
select * from test (1);
復制代碼
第三個事務,插入數據
begin;
insert into test values('3', '王五');
commit;
復制代碼
此時的數據,多了一條王五,它的創建版本號是當前事務編號,3:
idname創建版本刪除版本1張三1undefined
2李四1undefined
3王五3undefined
第二個事務執行第二次查詢
begin;
select * from test (2);
復制代碼
MVCC 的查找規則:只能查找創建時間小于等于當前事務 ID 的數據,和刪除時間大于當前事務 ID 的行(或未刪除)。
也就是不能查到在我的事務開始之后插入的數據,王五的創建 ID 大于 2,所以還是只能查到兩條數據。
第四個事務刪除數據,刪除id =2的李四這條數據
begin;
delete from test where id =2;
commit
復制代碼
此時的數據,jack的刪除版本被記錄為當前事務ID,4,其他數據不變
idname創建版本刪除版本1張三1undefined
2李四14
3王五3undefined
在第二個事務中,執行第 3 次查詢:
begin;
select * from test (3);
復制代碼
查找規則:只能查找創建時間小于等于當前事務ID的數據,和刪除時間大于當前事務ID的行(或未刪除)。也就是,在我事務開始之后刪除的數據,所以李四依然可以查出來。所以還是這兩條數據。
第五個事務,執行更新操作,這個事務事務 ID 是 5:
begin;
update test set name = '趙六' where ud =1
commit
復制代碼
此時的數據,更新數據的時候,舊數據的刪除版本被記錄為當前事務 ID 5,產生了一條新數據,創建 ID 為當前事務 ID 5:
idname創建版本刪除版本1張三15
2李四14
3王五3undefined
1趙六5undefined
第二個事務,執行第 4 次查詢:
begin;
select * from test (3);
復制代碼
因為更新后的數據趙六創建版本大于2,代表是在事務之后增加的,查不出來。而舊數據李四的刪除版本大于2,代表是在事務之后刪除的,可以查出來。
通過以上演示我們能看到,通過版本號的控制,無論其他事務是插入、修改、刪除,第一個事務查詢到的數據都沒有變化。
總結
以上是生活随笔為你收集整理的什么是mysql事物定义_Mysql事务原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷 P4016 负载平衡问题 【最小费
- 下一篇: linux cmake编译源码,linu