今天使用@Transcation注解的形式為serivce服務添加事物,但是無論如何都無法回滾!
在網上找了很多帖子,自己總結了一下.
開始說事務之前,不得不提一下java的異常類型:
分為checked異常和unchecked異常
checked異常:非系統原因造成的異常,比如需要Try - catch處理,或者throws拋出到上一層去,繼承自java.lang.Exception(不包括java.lang.RuntimeException)
unchecked異常:系統原因自己造成的異常,如空指針異常,類型轉換異常等,不需要在系統中顯示的捕獲處理。繼承自java.lang.RuntimeException
下面是注解形式的事物在Spring中的配置
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="transactionManager"></property> </bean> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class = "true" />
@Transaction(propagation=Propagation.NOT_SUPPORTED)
Propagation支持7種不同的傳播機制:
REQUIRED:如果存在一個事務,則支持當前事務。如果沒有事務則開啟一個新的事務。
SUPPORTS: 如果存在一個事務,支持當前事務。如果沒有事務,則非事務的執行。但是對於事務同步的事務管理器,PROPAGATION_SUPPORTS與不使用事務有少許不同。
NOT_SUPPORTED:總是非事務地執行,並掛起任何存在的事務。
REQUIRESNEW:總是開啟一個新的事務。如果一個事務已經存在,則將這個存在的事務掛起。
MANDATORY:如果已經存在一個事務,支持當前事務。如果沒有一個活動的事務,則拋出異常。
NEVER:總是非事務地執行,如果存在一個活動事務,則拋出異常
NESTED:如果一個活動的事務存在,則運行在一個嵌套的事務中。如果沒有活動事務,則按REQUIRED屬性執行。
事物無效的原因:
1.@Transactional 注解必須作用在public的權限管理上,其余的權限管理關鍵字並不會使事物生效
2.<tx:annotation-driven transaction-manager="transactionManager" /> 如果缺少了這一塊配置 那么事物的注解也會失效
3.通過元素的 “proxy-target-class” 屬性值來控制是基於接口的還是基於類的代理被創建。如果 “proxy-target-class” 屬值被設置為 “true”,那么基於類的代理將起作用。
如果 “proxy-target-class” 屬值被設置為 “false” 或者這個屬性被省略,那么標准的JDK基於接口的代理將起作用。
4.Spring團隊建議在具體的類(或類的方法)上使用 @Transactional 注解,而不要使用在類所要實現的任何接口上.
在接口上使用 @Transactional 注解,只能當你設置了基於接口的代理時它才生效(即配合proxy-target-class為true)
5.@Transactional 的事務開啟 ,或者是基於接口的 或者是基於類的代理被創建。在同一個類中一個方法調用另一個方法有事務的方法,事務是不會起作用的。
6.在web項目中往往都會配置spring容器與spring-mvc子容器,所以想讓事物在service中生效必須要區分2個容器的掃描對象,mvc就針對controller層掃描,其余的交給spring去控制
如果在mvc掃描所有的對象包括serivce,那么事物也會失效,所以2個容器的對象管理最好做下區分