事務(wù)與ACID屬性
- 原子性(Atomicity)
- 一致性(Consistency)
- 隔離性(Isolation)
- 持久性(Durable)
并發(fā)事務(wù)處理帶來的問題
- 更新丟失:兩個事務(wù)同時操作相同的數(shù)據(jù),后提交的事務(wù)會覆蓋先提交的事務(wù)的處理結(jié)果,通過樂觀鎖可以解決
- 臟讀:事務(wù)A讀取了事務(wù)B已經(jīng)修改但是沒有提交的數(shù)據(jù),如果B事務(wù)回滾,那么A讀取的數(shù)據(jù)無效,不符合一致性
- 不可重復(fù)讀:事務(wù)A讀取到了事務(wù)B已經(jīng)提交的修改數(shù)據(jù),不符合隔離性
- 幻讀:事務(wù)A讀取到了事務(wù)B提交的新增數(shù)據(jù),不符合隔離性
隔離級別
mysql中的隔離級別
| 隔離級別 | 臟讀(Dirty Read) | 不可重復(fù)讀(NonRepeatable Read) | 幻讀(Phantom Read) |
|---|---|---|---|
| (讀未提交) read uncommited | 可能 | 可能 | 可能 |
| (讀已提交)read commited | 不可能 | 可能 | 可能 |
| (可重復(fù)讀)repeatable read | 不可能 | 不可能 | 可能 |
| (可串行化)serializable | 不可能 | 不可能 | 不可能 |
查看當(dāng)前隔離級別信息
mysql8.0將tx_isolation改成transaction_isolation

圖片.png
實操
1、臟讀問題及解決
這個時候需要將Mysql中的隔離級別設(shè)置為:Read Uncommited
set session transaction isolation level read committed;
mysql> show variables like 'transaction_isolation';
+-----------------------+----------------+
| Variable_name | Value |
+-----------------------+----------------+
| transaction_isolation | READ-COMMITTED |
+-----------------------+----------------+
1 row in set, 1 warning (0.00 sec)
- Innodb行鎖
innodb會給更新語句加上行鎖

圖片.png
- 將當(dāng)前會話的的事務(wù)的隔離級別設(shè)置為Read Uncommitted
以下設(shè)置的是Read Committed,相關(guān)設(shè)置類似

圖片.png
- 臟讀問題出現(xiàn)
臟讀

圖片.png
- 臟讀問題解決
將隔離級別設(shè)置為Read Committed;
2、不可重復(fù)讀問題及解決
先將隔離級別設(shè)置為:Read Committed;
- 舊問題解決新問題出現(xiàn)

圖片.png
- 解決不可重復(fù)讀問題
記得要將隔離級別設(shè)置為Repeatable Read

圖片.png
- 坑
關(guān)于MVCC:multipart version concurrency control 多版本并發(fā)控制,在開啟一個事務(wù)后進行select查詢時,會默認為當(dāng)前事務(wù)建立一個讀取的快照(緩存),如果在另一個事務(wù)中執(zhí)行了更新操作并進行了提交,且當(dāng)前事務(wù)也進行了更新操作,那么快照中的緩存值將會更新

圖片.png
3、幻讀問題及解決
將隔離級別設(shè)置為Serializable,就會解決之前的所有情況,但是效率低下,很少使用