一、事務的四大特性(ACID)
- 原子性(Atomicity):原子性是指事務包含的所有操作要么全部成功,要么全部失敗回滾,因此事務的操作如果成功就必須要完全應用到數據庫,如果操作失敗則不能對數據庫有任何影響。
- 一致性(Consistency):一致性是指事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態,也就是說一個事務執行之前和執行之后都必須處於一致性狀態。舉例來說,假設用戶A和用戶B兩者的錢加起來一共是1000,那么不管A和B之間如何轉賬、轉幾次賬,事務結束后兩個用戶的錢相加起來應該還得是1000,這就是事務的一致性。
- 隔離性(Isolation):隔離性是當多個用戶並發訪問數據庫時,比如同時操作同一張表時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作所干擾,多個並發事務之間要相互隔離。關於事務的隔離性數據庫提供了多種隔離級別,稍后會介紹到。
- 持久性(Durability):持久性是指一個事務一旦被提交了,那么對數據庫中的數據的改變就是永久性的,即便是在數據庫系統遇到故障的情況下也不會丟失提交事務的操作。
二、事務的隔離級別
- 讀未提交(Read uncommitted):讀未提交,顧名思義,就是一個事務可以讀取另一個未提交事務的數據
- 讀已提交(Read committed):讀提交,顧名思義,就是一個事務要等另一個事務提交后才能讀取數據
- 重復讀(Repeatable read):就是在開始讀取數據(事務開啟)時,不再允許修改操作
- 串行化(Serializable): 是最高的事務隔離級別,在該級別下,事務串行化順序執行,可以避免臟讀、不可重復讀與幻讀。但是這種事務隔離級別效率低下,比較耗數據庫性能,一般不使用
會產生的三種問題:
- 臟讀:事務A正添加一條記錄,此時還未提交,事務B讀取到該記錄,事務B讀取的就是臟數據,這就是臟讀
- 不可重復讀:事務A開啟並讀取到一條記錄余額為1000,還未提交,此時事務B開啟事務,修改這條記錄余額為2000並提交,事務A再次讀取該記錄余額為2000,一個事務中兩次讀取的余額不一樣,這就是不可重復讀
- 幻讀:事務A開啟並讀取到只有一條記錄,還未提交,此時事務B開啟事務,添加一條記錄並提交,事務A再次讀取發現有兩條記錄了,仿佛產生幻覺,這就是幻讀
- 這里注意:不可重復讀針對的是修改操作,幻讀針對的是新增或者刪除記錄的操作
三、事務的傳播屬性
- PROPAGATION_REQUIRED – 支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇
- PROPAGATION_SUPPORTS – 支持當前事務,如果當前沒有事務,就以非事務方式執行
- PROPAGATION_MANDATORY – 支持當前事務,如果當前沒有事務,就拋出異常
- PROPAGATION_REQUIRES_NEW – 新建事務,如果當前存在事務,把當前事務掛起
- PROPAGATION_NOT_SUPPORTED – 以非事務方式執行操作,如果當前存在事務,就把當前事務掛起
- PROPAGATION_NEVER – 以非事務方式執行,如果當前存在事務,則拋出異常
- PROPAGATION_NESTED – 如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則進行與PROPAGATION_REQUIRED類似的操作