Spring並不直接管理事務,只有當數據庫支持事務時,Spring才支持事務
,Spring只不過簡化了開發人員實現事務的步驟,Spring提供了多種事務管理器,他們將事務管理的職責委託給Hibernate或者JTA等持久化機制所提供的相關平臺框架的事務
來實現。spring
Spring事務管理器的接口是org.springframework.transaction.PlatformTransactionManager,經過這個接口,Spring爲各個平臺如JDBC、Hibernate等都提供了對應的事務管理器,可是具體的實現就是各個平臺本身的事情了。此接口的內容以下:
數據庫
三個方法分別是:編程
PlatformTransactionManager中有個getTransaction(TransactionDefinition var1)方法,這個方法返回的是TransactionStatus對象,而後程序根據返回的對象來獲取事務狀態,而後進行相應的操做。
後端
幾個方法分別是:併發
事務屬性能夠理解成事務的一些基本配置,描述了事務策略如何應用到方法上。事務屬性包含了5個方面,如圖所示:框架
方法分別是: 3d
傳播行爲: 事務的第一個方面是傳播行爲(propagation behavior),當事務方法被另外一個事務方法調用時,必須指定事務應該如何傳播。
code
這裏以A業務和B業務之間如何傳播事務爲例說明:
orm
①、PROPAGATION_REQUIRED :默認值
,A若是有事務,B將使用該事務;若是A沒有事務,B將建立一個新的事務。cdn
②、PROPAGATION_SUPPORTS:A若是有事務,B將使用該事務;若是A沒有事務,B將以非事務執行。
③、PROPAGATION_MANDATORY:A若是有事務,B將使用該事務;若是A沒有事務,B將拋異常。
④、PROPAGATION_REQUIRES_NEW :若是A有事務,將A的事務掛起,B建立一個新的事務;若是A沒有事務,B建立一個新的事務。
⑤、PROPAGATION_NOT_SUPPORTED :若是A有事務,將A的事務掛起,B將以非事務執行;若是A沒有事務,B將以非事務執行。
⑥、PROPAGATION_NEVER :若是A有事務,B將拋異常;若是A沒有事務,B將以非事務執行。
⑦、PROPAGATION_NESTED :A和B底層採用保存點機制,造成嵌套事務。
傳播行爲: 事務的第一個方面是傳播行爲(propagation behavior),當事務方法被另外一個事務方法調用時,必須指定事務應該如何傳播。
定義了一個事務可能受其餘併發事務影響的程度。
併發事務引發的問題:
①、髒讀(Dirty reads)——髒讀發生在一個事務讀取了另外一個事務改寫但還沒有提交的數據時。若是改寫在稍後被回滾了,那麼第一個事務獲取的數據就是無效的。
②、不可重複讀(Nonrepeatable read)——不可重複讀發生在一個事務執行相同的查詢兩次或兩次以上,可是每次都獲得不一樣的數據時。這一般是由於另外一個併發事務在兩次查詢期間進行了更新。
③、幻讀(Phantom read)——幻讀與不可重複讀相似。它發生在一個事務(T1)讀取了幾行數據,接着另外一個併發事務(T2)插入了一些數據時。在隨後的查詢中,第一個事務(T1)就會發現多了一些本來不存在的記錄。
注意:不可重複讀重點是修改,而幻讀重點是新增或刪除。
在 Spring 事務管理中,爲咱們定義了以下的隔離級別:
後端數據庫默認
的隔離級別Spring 提供了兩種方式實現事務:①聲明式,②編程式。
聲明式事務管理只須要用到@Transactional 註解和@EnableTransactionManagement(開啓事務管理功能)。它是基於 Spring AOP
實現的,而且經過註解實現,實現起來簡單,對原有代碼沒有入侵性。
事務的切面有兩個主要職責:
①Transactional註解標註方法修飾符爲非public時,@Transactional註解將會不起做用。
②在類內部調用調用類內部@Transactional標註的方法。這種狀況下也會致使事務不開啓。
③事務方法內部捕捉了異常,沒有拋出新的異常,致使事務操做不會進行回滾。
④ 異常類型是否是unchecked異常。若是我想check異常也想回滾怎麼辦,註解上面寫明異常類型便可。@Transactional(rollbackFor=Exception.class)