• 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.

  • 相关阅读:
    环境装好,开始学习
    懒惰了
    我的net试验田
    时间不够用
    【转帖】关于委托的精彩解说(非常形象)
    【转帖】 CLR 全面透彻解析:托管和本机代码互操作性
    【转贴】C#中的API32
    【转帖】Windows Mobile 开发系列文章收藏 Windows Mobile 6.x
    弹跳圣经——扣篮梦
    【转帖】.Net中C#的DllImport的用法
  • 原文地址:https://www.cnblogs.com/alterem/p/11463452.html
Copyright © 2020-2023  润新知