数据库事物相关笔记
一、數據庫的事物的基本特性
事物是區分文件存儲系統與Nosql數據庫重要特性之一,其存在的意義是為了保證即使在并發情況下也能正確的執行crud操作。怎樣才算是正確的呢?這時提出了事物需要保證的四個特性即ACID:
- 事物中各項操作,要么全做要么全不做,任何一項操作的失敗都會導致整個事物的失敗;
- 事物結束后系統狀態是一致的;
- 并發執行的事物彼此無法看到對方的中間狀態;
- 事物完成后所做的改動都會被持久化,即使發生災難性的失敗。
在高并發的情況下,要完全保證其ACID特性是非常困難的,除非把所有的事物串行化執行,但帶來的負面的影響將是性能大打折扣。很多時候我們有些業務對事物的要求是不一樣的,所以數據庫中設計了四種隔離級別,供用戶基于業務進行選擇。
二、數據庫的事物的隔離級別
| 隔離級別 | 臟讀(Dirty Read) | 不可重復讀(NonRepeatable Read) | 幻讀(Phantom Read) |
| 未提交讀(Read uncommitted) | 可能 | 可能 | 可能 |
| 已提交讀(Read committed) | 不可能 | 可能 | 可能 |
| 可重復讀(Repeatable read) | 不可能 | 不可能 | 可能 |
| 可串行化(SERIALIZABLE) | 不可能 | 不可能 | 不可能 |
?
臟讀 :
一個事物讀取到另一事物未提交的更新數據
不可重復讀 :
在同一事物中,多次讀取同一數據返回的結果有所不同, 換句話說, 后續讀取可以讀到另一事物已提交的更新數據. 相反, “可重復讀”在同一事物中多次讀取數據時, 能夠保證所讀數據一樣, 也就是后續讀取不能讀到另一事物已提交的更新數據。
幻讀 :
?查詢表中一條數據如果不存在就插入一條,并發的時候卻發現,里面居然有兩條相同的數據。這就幻讀的問題。
?
數據庫默認隔離級別:
Oracle中默認級別是 Read committed
mysql 中默認級別 Repeatable read。另外要注意的是mysql 執行一條查詢語句默認是一個獨立的事物,所以看上去效果跟Read committed一樣。
# 查看mysql 的默認隔離級別
SELECT @@tx_isolation
?
三、事物的傳播機制
?
?
| 類別 | 事物傳播類型 | 說明 |
| 支持當前事物 | PROPAGATION_REQUIRED (必須的) | 如果當前沒有事物,就新建一個事物,如果已經存在一個事物中,加入到這個事物中。這是最常見的選擇。 |
| PROPAGATION_SUPPORTS (支持) | 支持當前事物,如果當前沒有事物,就以非事物方式執行。 | |
| PROPAGATION_MANDATORY (強制) | 使用當前的事物,如果當前沒有事物,就拋出異常。 | |
| 不支持當前事物 | PROPAGATION_REQUIRES_NEW (隔離) | 新建事物,如果當前存在事物,把當前事物掛起。 |
| PROPAGATION_NOT_SUPPORTED (不支持) | 以非事物方式執行操作,如果當前存在事物,就把當前事物掛起。 | |
| PROPAGATION_NEVER (強制非事物) | 以非事物方式執行,如果當前存在事物,則拋出異常。 | |
| 套事物 | PROPAGATION_NESTED (嵌套事物) | 如果當前存在事物,則在嵌套事物內執行。如果當前沒有事物,則執行與PROPAGATION_REQUIRED類似的操作。 |
常用事物傳播機制:
- 這個也是默認的傳播機制;
- 可以用于發送提示消息,站內信、短信、郵件提示等。不屬于并且不應當影響主體業務邏輯,即使發送失敗也不應該對主體業務邏輯回滾。
- 總是新啟一個事物,這個傳播機制適用于不受父方法事物影響的操作,比如某些業務場景下需要記錄業務日志,用于異步反查,那么不管主體業務邏輯是否完成,日志都需要記錄下來,不能因為主體業務邏輯報錯而丟失日志;
總結
- 上一篇: 【amtlib.dll文件下载】amtl
- 下一篇: springboot mybatis m