事務特性:
ACID
特性 | 說明 | |
---|---|---|
A 原子性(針對執行單元) | Atomic,一個事務並不一定是一條sql,可能是將多條sql捆綁在一塊,而原子性保證這一整塊的sql要都成功,要麼都失敗,然後回滾 | |
C一致性(針對整體狀態轉變)) | Consistency,事務保證讓數據庫從一個一致性狀態變換到另一個一致性狀態 | 比如a,b賬戶一共500,無論a,b間怎麼轉,事務結束後錢加起來都是500 |
I隔離性(針對併發事務) | Isolation,多個線程併發操作同一張表時,數據庫給每個線程開啓一個事務,不能被其他事務干擾,多個事務之間相互隔離 | 比如是兩個事務,A事務認爲B事務在A開始前結束,或者是A結束後纔開始 |
D持久性(針對數據保存) | Durablility,指的是一旦事務被提交,那麼對數據哭的影響必須是永久性的,即便在數據庫系統遇到故障的情況下也是這樣 | 比如系統宕機,事務一開始,就會將數據寫入到redolo文件中,提交後,redolog中的sql在內存中執行,數據寫入到緩衝中,然後定時將緩衝中數據刷入磁盤;然後刪除redolog 中相應記錄(此時持久化已經成功)如果斷電,緩衝中的數據會消失,但是redolog 中還有記錄,重啓自動執行relog內容 |
事務隔離性會出現的問題
以轉錢爲例
張三(老闆)與李四(職員)
術語 | 描述 | 簡化 |
---|---|---|
髒讀 | 張三開啓事務,給李四轉500塊,但是還未提交事務,然後通知張三去查詢餘額,發現錢到賬了,後面張三操作有誤,事務回滾,轉賬失敗 | 讀到未提交的數據 |
不可重複讀 | 單個事物多次查詢同一條記錄,但是返回的記錄在查詢間隔內被其他事務修改了,導致獲取到不同的值 | 注意與髒讀的區別:不可重複讀,是讀取到了前一個事務提交的數據,髒讀是讀取到其他事物未提交的數據 |
幻讀 | 張三給所有員工交社保,有一個字段標記爲是否繳納社保,設置爲1,這時候人事部新來了一位員工,將其記錄插入表中,而他的社保字段默認是0,如果張三再檢查一下是剛剛操作的繳納數據,發現還有一個沒繳納,而這個數據是來自其他事物的,就像是幻覺,這就是幻讀 | 與不可重複讀都是讀取到其他事物提交後的數據,但是幻讀針對的是一批數據(比如數據個數),不可重複讀是針對的同一個記錄 |
隔離級別
隔離級別 | 髒讀 | 不可重複讀 | 幻讀 |
---|---|---|---|
read-uncommitted 讀未提交 | 出現 | 出現 | 出現 |
read-committed 讀已提交 | 不會出現 | 出現 | 出現 |
repeatable-read 可重複讀 | 不會出現 | 不會出現 | 出現 |
serializable 串行化 | 不會出現 | 不會出現 | 不會出現 |
測試隔離級別
設置隔離級別以及查看當前session隔離級別
set session transaction level read committed;
-- level 後的參數可選值 爲 read committed/read uncommitted/ repeateable read/serializable
select @@tx_isolation;
1. 測試隔離級別:read-uncommitted(都是此隔離級別)
測試邏輯:
初始餘額899
A事務中加錢,B查詢餘額(變成了999)
A事務回滾,B查詢餘額(變成了899)
測試效果:
2 .測試隔離級別:read-committed
開啓session cmd 窗口,事物隔離級別都設置爲
read-committed:
set session transaction isolation level read committed;
測試邏輯:
初始餘額999
A事務加錢+100, B事務查詢餘額 999
A事務提交,B事務查詢餘額 1099
測試效果:
3. 測試隔離級別repeatable read
測試邏輯:
初始餘額爲899
事務A使用 read committed 隔離級別
事務B使用repeatable read 隔離級別
事務A加錢,事務B查詢餘額,依然是舊數據
事務A提交,事務B查詢餘額,依然是舊數據
事務B提交,查詢餘額,顯示新數據
測試效果:
4. 測試隔離級別serializable(串行化)
這完全將事務的併發性給消除掉,全部進行串行化開啓-提交
測試邏輯:
重點測試能否避免幻讀(同一事務對一批數據進行兩次查詢,查詢間隔內,這批數據被某個事務修改並提交)
A事務開啓,B事務開啓, 插入zhangsi記錄
A事務中查詢全部人員信息,發現會阻塞,沒有輸出,然後會輸出報錯
B事務提交
重新開啓A事務,查詢數據
發現zhangsi 數據被存入
串行化一般不會被使用,這完全是消除了數據庫的併發性能.
總結:
- 事務隔離級別說白了是描述的事務之間能否窺探到其他事物的過程中的某些狀態
- read-uncommitted:要求最低,可以讀取其他事物未提交的狀態
- read-committed:只能讀取到其他事物提交之後的狀態,或者是其他事物開始之前的狀態
- repeatable-read:當前事務內部只能讀取到開啓事務時刻的數據狀態,即使在此期間其他事物提交了相關數據修改的事物,也會是視而不見
- serializable:串行化,或者是序列化,所有的事務都在一個隊列中,只能按順序提交如果有事物在修改數據,其他事物也只能等待修改數據的事物提交後,才能查詢(可以理解爲給表加鎖)
參考博客:
隔離級別測試