1. 事務特性
事務特性:ACID
- 原子性:整體 【原子性是指事務包含的所有操作要么全部成功,要么全部失敗】
- 一致性:數據 【一個事務執行之前和執行之后都必須處於一致性狀態】
- 隔離性:並發 【對於任意兩個並發的事務T1和T2,在事務T1看來,T2要么在T1開始之前就已經結束,要么在T1結束之后才開始,這樣每個事務都感覺不到有其他事務在並發地執行。】
- 持久性:結果 【持久性是指一個事務一旦被提交了,那么對數據庫中的數據的改變就是永久性的】
隔離問題
- 臟讀:一個事務讀到另一個事務未提交的內容【讀取未提交內容】
在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。本隔離級別很少用於實際應用,因為它的性能也不比其他級別好多少。
- 不可重復讀:一個事務讀到另一個事務已提交的內容(insert)【讀取提交內容】
這是大多數數據庫系統的默認隔離級別(但不是MySQL默認的)。它滿足了隔離的簡單定義:一個事務只能看見已經提交事務所做的改變。
- 虛讀(幻讀):一個事務讀到另一個事務已提交的內容(update)
這是MySQL的默認事務隔離級別,它確保同一事務的多個實例在並發讀取數據時,會看到同樣的數據行。不過理論上,這會導致另一個棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當用戶讀取某一范圍的數據行時,另一個事務又在該范圍內插入了新行,當用戶再讀取該范圍的數據行時,會發現有新的“幻影” 行。
- Serializable(可串行化)
這是最高的隔離級別,它通過強制事務排序,使之不可能相互沖突,從而解決幻讀問題。簡言之,它是在每個讀的數據行上加上共享鎖。在這個級別,可能導致大量的超時現象和鎖競爭。
隔離級別--解決問題
- read uncommittd,讀未提交。存在3個問題。
- read committed,讀已提交。解決:臟讀。存在2個問題。
- repeatable read ,可重復讀。解決:臟讀、不可重復讀。存在1個問題。
- serializable,串行化。單事務。沒有問題。
2 Spring事務管理介紹
導入包
常用的事務管理器
TransactionStatus 事務狀態
TransactionDefinition 事務定義
傳播行為:在兩個業務之間如何共享事務
PROPAGATION_REQUIRED required , 必須 【默認值】 |
支持當前事務,A如果有事務,B將使用該事務。 如果A沒有事務,B將創建一個新的事務。 |
PROPAGATION_SUPPORTS supports ,支持 |
支持當前事務,A如果有事務,B將使用該事務。 如果A沒有事務,B將以非事務執行。 |
PROPAGATION_MANDATORY mandatory ,強制 |
支持當前事務,A如果有事務,B將使用該事務。 如果A沒有事務,B將拋異常。 |
PROPAGATION_REQUIRES_NEW requires_new ,必須新的 |
如果A有事務,將A的事務掛起,B創建一個新的事務 如果A沒有事務,B創建一個新的事務 |
PROPAGATION_NOT_SUPPORTED not_supported ,不支持 |
如果A有事務,將A的事務掛起,B將以非事務執行 如果A沒有事務,B將以非事務執行 |
PROPAGATION_NEVER never,從不 |
如果A有事務,B將拋異常 如果A沒有事務,B將以非事務執行 |
PROPAGATION_NESTED nested ,嵌套 |
A和B底層采用保存點機制,形成嵌套事務。 |
案例:轉帳
創建數據庫
導入包
l aop : 4 (aop聯盟、spring aop、aspectj規范、spring aspect)
l 數據庫:2 (jdbc/tx)
l 驅動:mysql
l 連接池:c3p0
l 核心:4+1
Dao層
Service層
Spring的配置
使用spring的工廠管理bean
測試類:
模擬轉賬失敗的結果如下
修改事務的隔離級別再次測試
測試報錯:
事務只讀 不可寫
模擬異常提交:
將轉賬失敗報錯的類加入隔離級別中
測試執行前數據庫數據:
執行測試
測試執行后數據庫數據: