1.概述
本教程将讨论配置Spring Transactions ,使用@Transactional批注和常见陷阱的正确方法 。
要更深入地讨论核心持久性配置,请查看Spring with JPA教程 。
有两种不同的配置事务的方法– 批注和AOP –每种都有自己的优势–我们将在这里讨论更常见的批注配置 。
2.在不使用XML的情况下配置事务
Spring 3.1引入了@EnableTransactionManagement批注 , 该批注将在@Configuration类中使用,并启用事务支持:
@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig{@Beanpublic LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(){...}@Beanpublic PlatformTransactionManager transactionManager(){JpaTransactionManager transactionManager = new JpaTransactionManager();transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject() );return transactionManager;}
}
3.使用XML配置事务
在3.1之前,或者如果不能使用Java,则这是XML配置 ,使用注释驱动和名称空间支持:
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager"><property name="entityManagerFactory" ref="myEmf" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
配置了事务后,现在可以在类或方法级别使用@Transactional注释Bean:
@Service
@Transactional
public class FooService {...
}
注释还支持进一步的配置 :
- 交易的传播类型
- 交易的隔离级别
- 事务包装的操作的超时
- readOnly标志 –持久性提供程序的提示,该事务应为只读
- 详细的回滚配置
5.潜在的陷阱
5.1。 交易和代理
在较高的级别上, Spring会在类或任何方法上为所有带有@Transactional注释的类创建代理 。 代理允许框架在调用方法之前和之后注入事务逻辑–主要用于启动和提交事务 。
要记住的重要一点是,如果事务Bean正在实现接口,则默认情况下,代理将是Java动态代理 。 这意味着将仅拦截通过代理传入的外部方法调用- 任何自调用将不会启动任何事务 -即使该方法使用@Transactional进行了注释。
使用代理的另一个警告是, 仅公共方法应使用@Transactional进行注释 -其他可见性的方法将仅默默地忽略该注释,因为这些代理没有被代理。
本文在这里详细讨论了进一步的代理pitfal 。
5.2。 更改隔离级别
将Spring配置为与JPA一起使用时的主要陷阱之一是,更改事务语义的隔离将不起作用– JPA不支持自定义隔离级别 。 这是JPA的限制, 不是Spring的限制; 但是,更改@Transactional 隔离属性将导致:
org.springframework.transaction.InvalidIsolationLevelException:标准JPA不支持自定义隔离级别–为您的JPA实现使用特殊的JpaDialect
5.3。 只读交易
readOnly标志通常会引起混乱,尤其是在使用JPA时; 从javadoc:
这只是实际交易子系统的提示。 它不一定会导致写访问尝试失败。 当请求只读事务时,无法解释只读提示的事务管理器不会引发异常。
事实是, 不能保证在设置readOnly标志时不会发生插入或更新-它的行为取决于供应商,而JPA与供应商无关。
同样重要的是要了解readOnly标志仅在事务内部相关; 如果操作发生在事务上下文之外,则仅忽略该标志。 一个简单的示例将调用带有以下注释的方法:
@Transactional( propagation = Propagation.SUPPORTS,readOnly = true )
从非事务上下文中-将不会创建事务,并且将忽略readOnly标志。
5.4。 交易记录
通过微调事务包中的日志记录 ,还可以更好地理解与事务相关的问题。 Spring中的相关软件包是“ org.springframework.transaction”,应使用TRACE的日志记录级别对其进行配置。
六,结论
我们介绍了同时使用Java和XML的事务语义的基本配置,如何使用@Transactional以及事务策略的最佳实践。 还讨论了Spring对事务测试的支持以及一些常见的JPA陷阱 。
这个简单项目的实现可以在github项目中找到–这是一个基于Eclipse的项目,因此应易于导入和运行。
翻译自: https://www.javacodegeeks.com/2011/12/transaction-configuration-with-jpa-and.html