Spring从3.1.11升级到3.3.3时触发TransactionRequiredException异常
Spring 3.1.11升级至3.3.3后TransactionRequiredException异常排查
问题描述
将Spring Framework从3.1.11版本升级至3.3.3版本后,执行数据库持久化操作时抛出以下异常:
jakarta.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:303) ~[spring-orm-6.1.12.jar!/:6.1.12] at jdk.proxy2/jdk.proxy2.$Proxy161.persist(Unknown Source) ~[na:na] at com.greenqloud.usage.nfsaas.dao.usage.AggregationLockManager.insertLock(AggregationLockManager.java:52) ~[!/:1.0.0] at com.greenqloud.usage.nfsaas.dao.usage.AggregationLockManager.aquireLock(AggregationLockManager.java:31) ~[!/:1.0.0] at com.greenqloud.usage.nfsaas.AggregationPipeline.processMetrics(AggregationPipeline.java:136) ~[!/:1.0.0] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Unknown Source) ~[na:na] at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:169) ~[spring-messaging-6.1.12.jar!/:6.1.12] at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:119) ~[spring-messaging-6.1.12.jar!/:6.1.12] at org.springframework.amqp.rabbit.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:75) ~[spring-rabbit-3.1.7.jar!/:3.1.7] at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:278) ~[spring-rabbit-3.1.7.jar!/:3.1.7] at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandlerAndProcessResult(MessagingMessageListenerAdapter.java:225) ~[spring-rabbit-3.1.7.jar!/:3.1.7] at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:149) ~[spring-rabbit-3.1.7.jar!/:3.1.7] at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1682) ~[spring-rabbit-3.1.7.jar!/:3.1.7] at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1604) ~[spring-rabbit-3.1.7.jar!/:3.1.7] at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1592) ~[spring-rabbit-3.1.7.jar!/:3.1.7] at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1583) ~[spring-rabbit-3.1.7.jar!/:3.1.7] at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListenerAndHandleException(AbstractMessageListenerContainer.java:1528) ~[spring-rabbit-3.1.7.jar!/:3.1.7] at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.lambda$executeListener$8(AbstractMessageListenerContainer.java:1506) ~[spring-rabbit-3.1.7.jar!/:3.1.7] at io.micrometer.observation.Observation.observe(Observation.java:499) ~[micrometer-observation-1.13.3.jar!/:1.13.3] at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1506) ~[spring-rabbit-3.1.7.jar!/:3.1.7] at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1082) ~[spring-rabbit-3.1.7.jar!/:3.1.7] at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1018) ~[spring-rabbit-3.1.7.jar!/:3.1.7] at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1421) ~[spring-rabbit-3.1.7.jar!/:3.1.7] at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1322) ~[spring-rabbit-3.1.7.jar!/:3.1.7] at java.base/java.lang.Thread.run(Unknown Source) ~[na:na]
已尝试在相关方法上添加@Transactional注解的多种组合,但异常仍未消除。当前使用org.glassfish jakarta.el(4.0.2)组件。
排查与解决方案
- 校验事务注解包路径:Spring 3.3.x基于Jakarta EE规范,必须使用
org.springframework.transaction.annotation.Transactional,禁止使用旧的javax.transaction.Transactional,确保注解导入正确。 - 确认事务管理器配置有效性:检查
JpaTransactionManager的配置,确保它绑定的EntityManagerFactory是项目中正在使用的实例,且该事务管理器被Spring上下文正确加载。可以通过打印容器中的Bean列表验证。 - 修复内部调用导致的事务失效:如果
processMetrics方法是通过Bean内部调用触发aquireLock,Spring代理无法拦截内部方法,@Transactional会失效。将AggregationLockManager作为独立Bean注入,通过外部调用触发事务方法;或者在@EnableTransactionManagement中设置proxyTargetClass = true启用CGLIB代理。 - 配置RabbitMQ监听器事务支持:异常发生在RabbitMQ消息处理流程中,需为监听器容器配置事务管理器。在容器配置中指定
transactionManager属性,确保消息消费和数据库操作处于同一事务上下文;或调整事务传播属性为Propagation.REQUIRED,强制开启事务。 - 统一Jakarta依赖版本:Spring 3.3.x要求Jakarta EE 9+,检查项目中所有Jakarta相关依赖(如
jakarta.persistence-api、jakarta.el-api)的版本是否兼容,避免混合使用javax和jakarta包导致的类路径冲突。 - 调试事务上下文状态:在
insertLock方法中添加调试代码,通过TransactionSynchronizationManager.isActualTransactionActive()判断当前线程是否存在活跃事务,定位事务未生效的具体环节。
内容的提问来源于stack exchange,提问作者azharuddin khan
相关产品推荐
相关产品推荐

