Spring JPA事務
[TOC]
1. 概述
本文將討論 配置Spring Transactions的正確方法,如何使用 @Transactional 註解和常見陷阱。
有關核心永續性配置的更深入討論,請檢視 Spring JPA教程。
通常,有兩種不同的方式來配置事務: 註解和AOP,
每個都有自己的優勢。 我們將在這裡討論更常見的註解配置。
促進閱讀:
為測試配置單獨的Spring DataSource
有關在Spring應用程式中配置單獨資料來源以進行測試的快速實用教程。
更多 →
使用Spring Boot載入初始資料的快速指南
在Spring Boot中使用data.sql和schema.sql檔案的快速實用示例。
更多 →
從Spring Boot顯示Hibernate / JPA SQL語句
瞭解如何在Spring Boot應用程式中配置生成的SQL語句的日誌記錄。
更多 →
2. 配置不帶XML的事務
Spring 3.1引入了@EnableTransactionManagement註釋,我們可以在@Configuration類中使用並啟用事務支援:
@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig{
@Bean
public LocalContainerEntityManagerFactoryBean
entityManagerFactoryBean(){
//...
}
@Bean
public PlatformTransactionManager transactionManager(){
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
entityManagerFactoryBean().getObject() );
return transactionManager;
}
}複製程式碼
但是,如果我們使用Spring Boot專案,並且在classpath上具有spring-data- *或spring-tx依賴項,則預設情況下將啟用事務管理。
3. 使用XML配置事務
在3.1之前通常使用annotation-driven namespace:
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="myEmf" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />複製程式碼
4. @Transactional 註解
通過配置事務,我們可以在bean的類和方法上使用@Transactional註解:
@Service
@Transactional
public class FooService {
//...
}複製程式碼
註解還支援進一步配置:
- 事務的轉播型別
- 事務的隔離級別
- 事務包裝操作的超時
- 只讀標誌 -提示永續性事務只讀
- 事務的回滾規則
請注意 - 預設情況下,僅對runtime,unchecked的異常進行回滾。 checked異常不會觸發事務的回滾。 當然,我們可以使用rollbackFor和noRollbackFor註解來配置異常回滾。
5. 潛在的陷阱
5.1. 事務和代理
在較高的層次上,spring為所有用@transactional註解的類建立代理,無論是在類上還是在方法上。代理允許框架在執行方法之前和之後注入事務邏輯,主要用於啟動和提交事務。
重要的是,如果正在實現事務bean的介面,預設情況下代理將是Java動態代理。這意味著只會攔截通過代理進入的外部方法呼叫。self-invocation呼叫時即使方法有@transactional註解也不會啟用事務。
使用代理的另一個注意事項是只有public方法才能用@transactional註解,在其他任何可見性的方法上進行註解時,這些方法都是沒有代理的,因為他們會忽略掉這些註解。
這裡有詳細的代理陷阱
5.2. 更改隔離級別
我們可以通過以下程式碼做事務隔離級別更改:
@Transactional(isolation = Isolation.SERIALIZABLE)複製程式碼
已經在Spring4.1中 引入; 如果我們在Spring4.1之前的版本上配置隔離級別:
org.springframework.transaction.InvalidIsolationLevelException: Standard JPA does not support custom isolation levels – use a special JpaDialect for your JPA implementation
5.3. 只讀事務
readonly標誌通常會產生混淆,尤其是在使用JPA時,以下來自Javadoc:
This just serves as a hint for the actual transaction subsystem; it will not necessarily cause failure of write access attempts. A transaction manager which cannot interpret the read-only hint will not throw an exception when asked for a read-only transaction.
實際上設定readOnly標誌後,並不能確定不會發生插入或更新。
同樣readOnly標誌只在事務中有用。如果在事務上下文之外,將會忽略這個標誌:
@Transactional( propagation = Propagation.SUPPORTS,readOnly = true )複製程式碼
將會忽略readOnly標誌
5.4. 事務日誌記錄
理解事務相關問題的最有效方法是對事務包中的日誌進行除錯。
可以設定"org.springframework.transaction"的日誌級別為"TRACE"。
6. 結論
使用Java和XML來介紹事務的基本配置,以及@Transactional的使用。