天天看點

Spring中@Transactional事務復原(含執行個體詳細講解,附源碼)

版權聲明:本文為部落客原創文章,轉載注明出處http://blog.csdn.net/u013142781

在了解@transactional怎麼用之前我們必須要先知道@transactional有什麼用。下面舉個栗子:比如一個部門裡面有很多成員,這兩者分别儲存在部門表和成員表裡面,在删除某個部門的時候,假設我們預設删除對應的成員。但是在執行的時候可能會出現這種情況,我們先删除部門,再删除成員,但是部門删除成功了,删除成員的時候出異常了。這時候我們希望如果成員删除失敗了,之前删除的部門也取消删除。這種場景就可以使用@transactional事物復原。

這裡之是以讓大家清楚checked異常和unchecked異常概念,是因為: 

checked異常: 

表示無效,不是程式中可以預測的。比如無效的使用者輸入,檔案不存在,網絡或者資料庫連結錯誤。這些都是外在的原因,都不是程式内部可以控制的。 

必須在代碼中顯式地處理。比如try-catch塊處理,或者給所在的方法加上throws說明,将異常抛到調用棧的上一層。 

unchecked異常: 

表示錯誤,程式的邏輯錯誤。是runtimeexception的子類,比如illegalargumentexception, nullpointerexception和illegalstateexception。 

不需要在代碼中顯式地捕獲unchecked異常做處理。 

繼承自java.lang.runtimeexception(而java.lang.runtimeexception繼承自java.lang.exception)。

看下面的異常結構圖或許層次感更加深些:

Spring中@Transactional事務復原(含執行個體詳細講解,附源碼)

本執行個體采用的是eclipse+maven,maven隻是作為jar管理,即便不了解的maven的猿友也可以讀懂。

3.1、spring的配置檔案

裡面必須先配置tx名字空間如下:

Spring中@Transactional事務復原(含執行個體詳細講解,附源碼)

為了使用基于@transactional的事務管理,需要在spring中進行如下的配置:

部落客的整個spring配置檔案:

3.2、使用@transactional,在添加使用者實作類方法加上注解

上面的方法我故意讓其出現空指針異常,會事物復原

3.3、運作單元測試類

發現無法插入進去,但是如果把@transactional去掉,即代碼如下,雖然出現異常,但是資料庫中還是有添加對應資料的:

Spring中@Transactional事務復原(含執行個體詳細講解,附源碼)

3.4、源碼下載下傳

本文最終源碼下載下傳:

<a href="http://download.csdn.net/detail/u013142781/9381184">http://download.csdn.net/detail/u013142781/9381184</a>

spring中的@transactional基于動态代理的機制,提供了一種透明的事務管理機制,友善快捷解決在開發中碰到的問題。

一般使用是通過如下代碼對方法或接口或類注釋:

1

propagation支援7種不同的傳播機制:

required:如果存在一個事務,則支援目前事務。如果沒有事務則開啟一個新的事務。

supports: 如果存在一個事務,支援目前事務。如果沒有事務,則非事務的執行。但是對于事務同步的事務管理器,propagation_supports與不使用事務有少許不同。

not_supported:總是非事務地執行,并挂起任何存在的事務。

requiresnew:總是開啟一個新的事務。如果一個事務已經存在,則将這個存在的事務挂起。

mandatory:如果已經存在一個事務,支援目前事務。如果沒有一個活動的事務,則抛出異常。

never:總是非事務地執行,如果存在一個活動事務,則抛出異常

nested:如果一個活動的事務存在,則運作在一個嵌套的事務中。如果沒有活動事務,則按required屬性執行。

下面是一些需要注意的事項,必須必須必須要看,不然遇到各種坑别說部落客沒有提醒你哦:

在需要事務管理的地方加@transactional 注解。@transactional 注解可以被應用于接口定義和接口方法、類定義和類的 public 方法上。

@transactional 注解隻能應用到 public 可見度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @transactional 注解,它也不會報錯, 但是這個被注解的方法将不會展示已配置的事務設定。

注意僅僅 @transactional 注解的出現不足于開啟事務行為,它僅僅 是一種中繼資料。必須在配置檔案中使用配置元素,才真正開啟了事務行為。

通過 元素的 “proxy-target-class” 屬性值來控制是基于接口的還是基于類的代理被建立。如果 “proxy-target-class” 屬值被設定為 “true”,那麼基于類的代理将起作用(這時需要cglib庫cglib.jar在classpath中)。如果 “proxy-target-class” 屬值被設定為 “false” 或者這個屬性被省略,那麼标準的jdk基于接口的代理将起作用。

spring團隊建議在具體的類(或類的方法)上使用 @transactional 注解,而不要使用在類所要實作的任何接口上。在接口上使用 @transactional 注解,隻能當你設定了基于接口的代理時它才生效。因為注解是 不能繼承 的,這就意味着如果正在使用基于類的代理時,那麼事務的設定将不能被基于類的代理所識别,而且對象也将不會被事務代理所包裝。

@transactional 的事務開啟 ,或者是基于接口的 或者是基于類的代理被建立。是以在同一個類中一個方法調用另一個方法有事務的方法,事務是不會起作用的。