天天看點

Spring中的@Transactional注解注意事項

Spring中的@Transactional必須要了解的概念

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

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

[html] view plain copy

  1. @Transactional(propagation=Propagation.NOT_SUPPORTED)  

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

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

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

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

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

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

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

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

下面是一些需要注意的事項:

  1. 在需要事務管理的地方加@Transactional 注解。@Transactional 注解可以被應用于接口定義和接口方法、類定義和類的 public 方法上。
  2. @Transactional 注解隻能應用到 public 可見度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不會報錯, 但是這個被注解的方法将不會展示已配置的事務設定。
  3. 注意僅僅 @Transactional 注解的出現不足于開啟事務行為,它僅僅 是一種中繼資料。必須在配置檔案中使用配置元素,才真正開啟了事務行為。
  4. 通過 元素的 “proxy-target-class” 屬性值來控制是基于接口的還是基于類的代理被建立。如果 “proxy-target-class” 屬值被設定為 “true”,那麼基于類的代理将起作用(這時需要CGLIB庫cglib.jar在CLASSPATH中)。如果 “proxy-target-class” 屬值被設定為 “false” 或者這個屬性被省略,那麼标準的JDK基于接口的代理将起作用。
  5. Spring團隊建議在具體的類(或類的方法)上使用 @Transactional 注解,而不要使用在類所要實作的任何接口上。在接口上使用 @Transactional 注解,隻能當你設定了基于接口的代理時它才生效。因為注解是 不能繼承 的,這就意味着如果正在使用基于類的代理時,那麼事務的設定将不能被基于類的代理所識别,而且對象也将不會被事務代理所包裝。
  6. @Transactional 的事務開啟 ,或者是基于接口的 或者是基于類的代理被建立。是以在同一個類中一個方法調用另一個方法有事務的方法,事務是不會起作用的。
  7. b調用a a方法的事務不會起作用
    Spring中的@Transactional注解注意事項