1.事務的四大特征
ACID
原子性(Automicity):不可分割的最小單位,要么同時成功,要么同時失敗。
持久性(Durablity):當事務提交或回滾之后,數據庫會持久化的保存數據。
隔離性(Isolation):多個事務之間相互獨立。事務的隔離性是多個用戶並發訪問數據庫時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作數據所干預,事務之間要相互隔離。
一致性(Consistency):事務操作前后,數據總量不變。
(1)原子性
針對同一個事務

這個過程包含兩個步驟
A: 800 - 200 = 600
B: 200 + 200 = 400
原子性表示,這兩個步驟一起成功,或者一起失敗,不能只發生其中一個動作。
(2)持久性
表示事務結束后的數據不隨着外界原因導致數據丟失
操作前A:800,B:200
操作后A:600,B:400
如果在操作前(事務還沒有提交)服務器宕機或者斷電,那么重啟數據庫以后,數據狀態應該為
A:800,B:200
如果在操作后(事務已經提交)服務器宕機或者斷電,那么重啟數據庫以后,數據狀態應該為
A:600,B:400
(3)隔離性
針對多個用戶同時操作,主要是排除其他事務對本次事務的影響

兩個事務同時進行,其中一個事務讀取到另外一個事務還沒有提交的數據


(4)一致性
針對一個事務操作前與操作后的狀態一致

操作前A:800,B:200
操作后A:600,B:400
一致性表示事務完成后,符合邏輯運算
2.事務隔離級別
(1)概念
多個事務之間隔離的,相互獨立的,但是如果多個事務操作同一批數據,則會引發一些問題,設置不同的隔離級別就可以解決這些問題。
(2)存在問題
臟讀:一個事務,讀取到另一個事務中沒有提交的數據
不可重復讀(虛讀):在同一個事務中,兩次讀取的數據不一樣
幻讀:一個事務操作(DML)數據表中所有記錄,另一個事務添加了一條數據,則第一個事務查詢不到自己的修改。
(3)隔離級別
- read uncommited:讀未提交
設置這樣的數據庫隔離級別,會產生的問題:臟讀、不可重復讀、幻讀
- read commited:讀已提交(ORACLE默認)
產生的問題:不可重復讀、幻讀
- repeatable read:可重復讀(MySQL默認)
產生的問題:幻讀
- serializable:串行化
可以解決所有的問題。其實就是一個鎖表的動作,如果一個事務在操作一張數據表,另外一個事務是不可以操作這張表的,只有當這個鎖打開之后,才可以操作。但是這樣的效率會很低。
注意:隔離級別從小到大安全性越來越高,但是效率越來越低
數據庫查詢隔離級別:
select @@tx_isolation;

數據庫設置隔離級別:
set global transaction isolation level 級別字符串;

下面演示臟讀和不可重復讀的情況:(注意兩邊都要開啟事務才能看到)
zhangsan這邊開了一個窗口:執行下面的操作

lisi這邊開了個窗口:查看錢是否到賬:

lisi發現錢到賬了
之后,zhangsan又執行了一步回滾的操作

lisi再去查,發現錢並沒有轉過來,這樣就發生了臟讀,不可重復讀


隔離級別設置成可重復讀:
zhangsan賬戶:

lisi賬號:


串行化:
其實就是一個鎖表的動作,如果一個事務在操作一張數據表,另外一個事務是不可以操作這張表的,只有當這個鎖打開之后,才可以操作。但是這樣的效率會很低。
set global transaction isolation level serializable;
start transaction;
-- 轉賬操作:
update account set money = money - 500 where id = 1;
update account set money = money + 500 where id = 2;
select @@tx_isolation;



