Spring JPA事務


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異常不會觸發事務的回滾。 當然,我們可以使用rollbackFornoRollbackFor注解來配置異常回滾。

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

Github.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM