交易需要例外JPA / Spring
我在存储库类中有一个标记为@Transactional
,正在堆栈跟踪中看到正在执行的方面,但抛出的exception是“Transaction required exception”
我将@Repository注释更改为@Component
(似乎它在某些情况下解决了这个问题),但它仍然在Web角色上发生。
这是堆栈跟踪:
2015-04-13 08:00:56,497 [http-nio-8080-exec-9] WARN es.mycompany.util.filters.MyFilter - Error storing : /admin/online/update org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:410) at org.springframework.orm.jpa.aspectj.JpaExceptionTranslatorAspect.ajc$afterThrowing$org_springframework_orm_jpa_aspectj_JpaExceptionTranslatorAspect$1$18a1ac9(JpaExceptionTranslatorAspect.aj:37) at es.mycopmany.dao.MyDAO.updateLastUpdatedTs_aroundBody2(MyDAO.java:36) at es.mycopmany.dao.MyDAO$AjcClosure3.run(MyDAO.java:1) at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(AbstractTransactionAspect.aj:66) at org.springframework.transaction.aspectj.AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation(AbstractTransactionAspect.aj:72) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:70) at es.mycompany.dao.MyDAO.updateLastUpdatedTs(MyDAO.java:31)
以下是抛出exception的代码:
@Transactional public void updateLastUpdatedTs(String id, Calendar date) { Query query = entityManager.createQuery("update MyEntity set lastUpdatedTs = :ts " + " where id= :id"); query.setParameter("ts", date); query.setParameter("id", id); query.executeUpdate(); }
事务性注释来自org.springframework.transaction.annotation.Transactional
版本:
Spring: 4.1.5.RELEASE Hibernate: 4.3.8.Final Aspectj: 1.8.5 Tomcat 8.0.20
配置:
EMF:
交易方式:
我真的很疯狂,任何帮助都会很棒。
请注意,这一切在我的开发环境(Windows,Idea Tomcat 8,JDK 8.0.31(Oracle))上完全正常 ,但它在Amazon EC2 Elasticbeanstalk(Tomcat 8,64位Amazon Linux 2015.03,Open JDK 8.0)上引发了此错误。 31(试图从Oracle使用8.0.40)
编辑 :更多信息:在整个filter链的末尾,filter抛出exception。
以下是exception之前的一些调试信息:
2015-04-13 14:57:48,578 [http-bio-8080-exec-7] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Creating new transaction with name [MyService.myMethod]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 2015-04-13 14:57:48,578 [http-bio-8080-exec-7] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Opened new EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@33f67ee5] for JPA transaction 2015-04-13 14:57:48,580 [http-bio-8080-exec-7] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@3112368a] 2015-04-13 14:57:48,581 [http-bio-8080-exec-7] TRACE org.springframework.transaction.support.TransactionSynchronizationManager - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@3193771b] for key [HikariDataSource (HikariPool-1)] to thread [http-bio-8080-exec-7] 2015-04-13 14:57:48,581 [http-bio-8080-exec-7] TRACE org.springframework.transaction.support.TransactionSynchronizationManager - Bound value [org.springframework.orm.jpa.EntityManagerHolder@497d4e44] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@5019da97] to thread [http-bio-8080-exec-7] 2015-04-13 14:57:48,581 [http-bio-8080-exec-7] TRACE org.springframework.transaction.support.TransactionSynchronizationManager - Initializing transaction synchronization 2015-04-13 14:57:48,581 [http-bio-8080-exec-7] TRACE org.springframework.transaction.aspectj.AnnotationTransactionAspect - Getting transaction for [MyService.myMethod] 2015-04-13 14:57:48,581 [http-bio-8080-exec-7] TRACE org.springframework.transaction.support.TransactionSynchronizationManager - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@497d4e44] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@5019da97] bound to thread [http-bio-8080-exec-7] 2015-04-13 14:57:48,581 [http-bio-8080-exec-7] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Found thread-bound EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@33f67ee5] for JPA transaction 2015-04-13 14:57:48,581 [http-bio-8080-exec-7] TRACE org.springframework.transaction.support.TransactionSynchronizationManager - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@3193771b] for key [HikariDataSource (HikariPool-1)] bound to thread [http-bio-8080-exec-7] 2015-04-13 14:57:48,581 [http-bio-8080-exec-7] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Participating in existing transaction 2015-04-13 14:57:48,581 [http-bio-8080-exec-7] TRACE org.springframework.transaction.aspectj.AnnotationTransactionAspect - Getting transaction for [MyDao.updateLastUpdatedTs] 2015-04-13 14:57:48,581 [http-bio-8080-exec-7] DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils - Opening JPA EntityManager 2015-04-13 14:57:48,582 [http-bio-8080-exec-7] DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils - Registering transaction synchronization for JPA EntityManager 2015-04-13 14:57:48,582 [http-bio-8080-exec-7] TRACE org.springframework.transaction.support.TransactionSynchronizationManager - Bound value [org.springframework.orm.jpa.EntityManagerHolder@4f83552c] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@7cc8111c] to thread [http-bio-8080-exec-7] 2015-04-13 14:57:48,608 [http-bio-8080-exec-7] TRACE org.springframework.transaction.support.TransactionSynchronizationManager - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@4f83552c] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@7cc8111c] bound to thread [http-bio-8080-exec-7] 2015-04-13 14:57:48,608 [http-bio-8080-exec-7] TRACE org.springframework.transaction.aspectj.AnnotationTransactionAspect - Completing transaction for [MyDao.updateLastUpdatedTs] after exception: org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
实际上,它创建了事务,然后它加入了事务(现在有两个@Transactionals,一个在服务层,另一个在DAO层),然后由于exception“它回滚事务”需要交易“。
这很坚果。
编辑嗯,我找到了这行调试:
2015-04-13 15:27:44,174 [http-bio-8080-exec-2] DEBUG org.springframework.orm.jpa.JpaTransactionManager – 参与交易失败 – 将现有交易标记为仅回滚
这里的值是:propagation = REQUIRED,isolation = DEFAULT
似乎有一个事务被检查为已完成,并且加入事务失败,因此它将其标记为仅回滚,因为它无法加入它。
我更改了注释驱动的配置,只需添加proxy-target-class =“true”似乎已解决了我们在亚马逊上海的某个环境(东南部),但欧洲(欧洲西部)的问题,问题仍在发生。 这是一场噩梦,所有配置完全相同(它只指向不同的db和s3)
解:
毕竟我终于得到了一些东西。 这解决了它(至少显然)。
原因:显然它与Spring初始化有关,并且在初始化完成之前调度一些任务,并且搞砸了。
我在服务层使用REQUIRES_NEW传播设置事务注释,以强制创建新事务。
@Transactional(propagation = Propagation.REQUIRES_NEW)
从DAO图层中删除了@Transactional
。
我还必须对连接器进行一些更改,增加maxThreads和max / min备用线程。
我还将所有@Scheduled初始化任务更改为在tomcat启动后10分钟开始
在所有这些改变之后,错误就消失了。
注意我还删除了之前的更改:“ proxy-target-class =”true“ ”,它仍然正常工作,所以这里不是一个很好的解决方案,但它可能对你有用,就像它对我一样一些情况(后台任务)。
正如旁注所示,我必须做的另一个改变是将@Repository
更改为@Component
,因为有些事务没有在计划任务上写入DB。
spring不是专家,但希望这会有所帮助。
几天前,阅读Spring文档中的类似问题,我发现:
特别是,您不需要仅通过EJB进行声明式事务的应用程序服务器。 实际上, 即使您的应用程序服务器具有强大的JTAfunction,您也可以决定Spring Framework的声明性事务提供比EJB CMT 更强大的function和更高效的编程模型。
AFAIK,在我们的服务中,我们声明交易更具体,以避免一些问题,如:
@Transactional ( propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Throwable.class )
如果您的注释仅适用于某些服务器,请在声明注释时尝试具体说明以覆盖您的事务方案。 通过这种方式,我猜你将在所有服务器中实现相同的行为。
- Hibernate持续vs保存
- 如何使用Hibernate注释在连接表上创建索引?
- 自JPA 2.1以来如何命名ManyToOne引用的外键约束?
- 使用SpringBoot和Hibernate与复合pks的双向@OneToMany关系
- 使用哪一个:OpenSessionInViewInterceptor或OpenSessionInViewFilter?
- 嵌套事务用例中的外部事务没有看到数据库中持久存在的更新(JPA,MySQL,Spring Framework和Hibernate)
- 可以在另一个查询的结果集上选择HQL吗?
- 在hibernate中使用逆true
- 无法阻止Hibernate将日志写入控制台(log4j.properties没问题)