jpa在定时任务中执行失败-TransactionRequiredException
jpa在定时任务中执行失败问题排查与解决
·
前言
有个老项目的部分模块采用了jpa做持久化框架,由于以前测试不到位,最近发现许多定时任务都没正确执行,但是直接调用接口并不会报错,唯独定时任务执行的时候会抛错,如下:
org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
排查过程
看日志是事务方面的问题,由于jpa要求执行更新/删除时,必须支持事务,即需要加上 @Transactional 注解,当然这种我已经加上了,所以直接调用并不会报错,猜测可能是事务管理器的问题,首先在启动类上加上 @EnableTransactionManagement 注解,然后手动添加jpa的事务管理器:
@Bean(name = "transactionManager")
public PlatformTransactionManager configurationTm(EntityManagerFactory managerFactory){
return new JpaTransactionManager(managerFactory);
}
重启后发现并没什么用,而且经过测试事务确实是生效的,只是在执行sql时会报错,然后今天早上突然想到由于该项目比较复杂,既用了jpa,也用了mybatis,会不会是这jpa事务管理器没成功创建,然后打印了一下当前的事务管理器:
@Bean
public Object testBean(PlatformTransactionManager platformTransactionManager){
System.out.println("看看当前事务管理器是谁:" + platformTransactionManager.getClass().getName());
return new Object();
}
惊喜的发现生效的是默认的jdbc事务管理器,即
org.springframework.jdbc.datasource.DataSourceTransactionManager
说明jpa的事务管理器并没生效,现在就好办了,调整代码如下:
@Primary
@Bean(name = "jpaTransactionManager")
public PlatformTransactionManager configurationTm(EntityManagerFactory managerFactory){
return new JpaTransactionManager(managerFactory);
}
由于该项目依赖的某个底层包中默认也初始化了 DataSourceTransactionManager ,因此需要加上 @Primary 注解,此时再次查看当前项目所用的事务管理器:
org.springframework.orm.jpa.JpaTransactionManager
最后在定时任务的方法上加上指定的事务管理器:
@Transactional(value = "jpaTransactionManager")
运行发现一切都恢复正常了~
最后扯一句,如果你的项目添加了 spring-boot-starter-data-jpa 依赖,那么框架会默认注入 JpaTransactionManager 实例,或者说你的项目是纯jpa,那么解决方式只会更简单~
更多推荐
已为社区贡献4条内容
所有评论(0)