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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章