[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的使用。