031_mysql事务的安全隐患
一. 事務的安全隱患
1. 讀的安全隱患
1.1. 臟讀: 一個事務讀到另外一個事務還未提交的數據。事務A讀取了事務B更新的數據, 然后B回滾操作, 那么A讀取到的數據是臟數據。
1.2. 不可重復讀: 一個事務讀到了另外一個事務提交的數據, 造成了前后兩次查詢結果不一致。事務A多次讀取同一數據, 事務B在事務A多次讀取的過程中,對數據作了更新并提交, 導致事務A多次讀取同一數據時, 結果不一致。
1.3. 幻讀: 一個事務讀到了另一個事務insert的數據, 造成前后查詢結果不一致。系統管理員A將數據庫中所有學生的成績從具體分數改為ABCDE等級, 但是系統管理員B就在這個時候插入了一條具體分數的記錄, 當系統管理員A改結束后發現多出了一條記錄, 就好像發生了幻覺一樣, 這就叫幻讀。
1.4. 不可重復讀的和幻讀很容易混淆, 不可重復讀側重于修改, 幻讀側重于新增或刪除。解決不可重復讀的問題只需鎖住滿足條件的行, 解決幻讀需要鎖表。
二. 事務的隔離級別
1. 查詢當前的mysql8的默認隔離級別。
2. 隔離級別第一級別: 讀未提交(read-uncommitted)
2.1. 打開客戶端A, 先將事務的隔離級別設定為讀未提交, 并開啟事務。
2.2. 客戶端A, 查詢用戶信息。
2.3. 客戶端A未提交事務, 打開客戶端B, 并開啟事務, 扣除客戶1的100塊錢, 不提交事務。
2.4. 客戶端B未提交事務, 客戶端A查看用戶信息, 查到了客戶端B更新的數據。
2.5. 客戶端B執行了回滾操作, 那么客戶端A之前讀到的數據就是臟數據。
2.6. 此時, 客戶端A減少客戶1的100塊錢, 發現執行前后, 客戶1都是900塊, 并沒有變成800塊。因為, 客戶端A讀到了客戶端B更新的數據, 后來客戶端B又回滾了數據, 客戶端A讀到了一條臟數據。
3. 讀已提交(第二級別 read-committed)
3.1. 讀已提交解決了臟讀問題, 但是出現了不可重復讀問題, 存在幻讀問題。
3.2. 打開客戶端A, 設置當前的事務隔離級別為read committed(未提交讀), 開啟事務, 查詢表Account的所有記錄。
3.3. 打開客戶端B, 開啟事務, 減少客戶1的100塊錢, 未提交事務。
3.4. 客戶端A, 在客戶端B更新數據前后, 查詢的數據一樣, 解決了臟的問題。
3.5. 客戶端B提交事務。
3.6. 客戶端A查詢到了客戶端B提交的數據。產生了不可重復讀的問題, 客戶端A進行同樣的2次查詢, 2次查詢結果不一致。
4. 可重復讀(第三級別 repeatable read)
4.1. 打開客戶端A, 設置當前的事務隔離級別為repeatable read (可重復讀), 開啟事務, 查詢表Account的所有記錄。
4.2. 打開客戶端B, 開啟事務, 扣除客戶1的100塊錢, 未提交事務。
4.3. 客戶端B更新數據, 未提交事務, 查詢客戶端A, 客戶端B更新數據前后, 客戶端的數據不變, 解決了臟讀問題。
4.4. 客戶端B提交事務。
4.5. 客戶端B提交事務后, 查詢客戶端A, 數據依然不變。
4.6. 客戶端B重新開啟事務, 插入一條數據, 并且提交事務。
4.7. 客戶端B插入一條數據, 并且提交事務后, 客戶端A查詢數據, 依然是以前的數據。客戶端A提交事務后, 查詢出了最新數據。
5. 可串行化(第四級別 serializable)
5.1. 打開客戶端A, 設置事務隔離級別為可串行化, 開啟事務, 查詢Account表。
5.2. 打開客戶端B, 開啟事務, 查詢Account表, 客戶端B可以進行查詢操作。
5.3. 在客戶端B, 執行一個更新操作, 客戶端B卡住了, 如果此時客戶端A提交或回滾事務, 客戶端B會更新成功; 如果客戶端A長時間沒有提交或回滾事務, 客戶端B的更新操作就超時報錯。
5.4. 如果有一個連接的隔離級別設置為了串行化, 那么誰先打開了事務, 就會在整張表上加了一個鎖, 其它事務不能進行寫操作。這種事務隔離級別解決了所有的安全問題。但是這種隔離級別一般比較少用, 容易造成性能上的問題, 效率比較低。
6.事務的隔離級別, 按效率劃分, 從高到低: 讀未提交-->讀已提交-->可重復讀-->可串行化。
7.事務的隔離級別, 按攔截程度, 從高到底: 可串行化-->可重復讀-->讀已提交-->讀未提交。
8. MySQL和Oracle默認的事務隔離級別
8.1. MySQL默認的事務隔離級別是: 可重復讀。
8.2. Oracle默認的事務隔離級別是: 讀已提交。
9. 隔離級別
9.1. 讀未提交, 引發問題臟讀。?
9.2. 讀已提交, 解決臟讀, 引發不可重復讀。
9.3. 可重復讀, 解決臟讀、不可重復讀、幻讀。
9.4. 可串行化, 解決臟讀、不可重復讀、幻讀, 同時似乎給整張表添加了一個鎖, 客戶并發讀, 但不能并發寫。
10. 悲觀鎖(排它鎖)
10.1. 丟失更新
10.2. 悲觀鎖
10.3. 客戶端A開啟事務, 給用戶1的減少100塊, 沒有提交事務。
10.4. 客戶端B開啟事務, 刪除用戶1, 客戶端B卡頓了, 超時報錯。
10.5. 客戶端A提交事務。
10.6. 客戶端B刪除用戶1成功。
總結
以上是生活随笔為你收集整理的031_mysql事务的安全隐患的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 020_MySQL运算符
- 下一篇: 003_Spring使用Slf4j和lo