java - 事务需要异常 JPA/Spring

标签 java spring hibernate jpa transactions

我在存储库类中有一个标记为 @Transactional 的方法,该方面正在执行,如堆栈跟踪中所示,但抛出的异常是“需要事务的异常”

我将 @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)

下面是抛出异常的代码:

    @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

配置:

电磁场:

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        id="entityManagerFactory">
        <property name="persistenceUnitName" value="athena" />
        <property name="dataSource" ref="dataSource" />
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
        </property>
    </bean>

交易:

<bean class="org.springframework.orm.jpa.JpaTransactionManager"
        id="transactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager" />

我真的要疯了,任何帮助都会很棒。

请注意,这一切在我的开发环境(Windows、Idea Tomcat 8、JDK 8.0.31(Oracle 的))上完全正常,但它在 Amazon EC2 Elasticbeanstalk(Tomcat 8 , 64 位 Amazon Linux 2015.03, 打开 JDK 8.0.31(也尝试使用 Oracle 的 8.0.40)

编辑:更多信息:异常在整个过滤器链末尾的过滤器上抛出。

这是异常发生前的一些调试信息:

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层),然后回滚事务,由于异常“需要交易”。

这太疯狂了。

编辑 好吧,我找到了这行调试:

2015-04-13 15:27:44,074 [http-bio-8080-exec-2] DEBUG org.springframework.orm.jpa.JpaTransactionManager - 参与事务失败 - 将现有事务标记为仅回滚

这里的值是:propagation=REQUIRED, isolation=DEFAULT

似乎有一个事务,检查为已完成,加入事务失败,所以将其标记为回滚,因为它无法加入。

最佳答案

我更改了注释驱动的配置,仅通过添加 proxy-target-class="true" 似乎已经解决了我们其中一个问题环境(ap-southeast)是亚马逊上海,但是对于欧洲(eu-west),问题仍然存在。这是一场噩梦,所有的配置都完全一样(只是指向不同的db&s3)

<tx:annotation-driven mode="aspectj" proxy-target-class="true" transaction-manager="transactionManager" />

<罢工>

解决方案:

毕竟,我终于得到了一些东西。这修复了它(至少显然是这样)。

原因: 显然它与 spring 初始化有关,并在初始化完成之前安排了一些任务,并且有些事情搞砸了。

我使用 REQUIRES_NEW 传播在服务层设置事务注解,以强制创建新事务。

@Transactional(propagation = Propagation.REQUIRES_NEW)

删除了 @Transactional来自 DAO 层。

我还必须对连接器进行一些更改,增加 maxThreads 和最大/最小备用线程。

我还更改了我所有的@Scheduled 初始化任务,使其在 tomcat 启动后 10 分钟开始

所有这些更改后,错误消失了。

注释 我还删除了之前的更改:“proxy-target-class="true"”,它仍然可以正常工作,所以这并不是一个很好的修复方法,但它可能对你有用正如它在某些情况下对我所做的那样(后台任务)。

作为旁注,我必须做的另一项更改是更改 @Repository@Component ,因为一些事务没有在计划任务中写入数据库。

关于java - 事务需要异常 JPA/Spring,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29601028/

相关文章:

java - 频繁发送到spring-websocket session : lost in transit

database - Hibernate外键约束多个数据库

java - 为什么这个java代码返回负值,我怎样才能将它转换为delphi?

java - Android中传递 vector 、获取ArrayList

java - 使用 JNDI 在 Spring Boot 中配置多个数据源

java - 为什么基本的 spring 4 示例不能使用 Eclipse kepler 运行?

java - Envers - 未找到 MappedSuperclass 属性。 @AuditMappedBy 指向不存在的属性

java - org.apache.struts2.json.JSONException : org. hibernate.LazyInitializationException:未能延迟初始化集合

java - 将另一个类的 JTextarea 输出组合到主类框架的 JTextArea 中?

java - 我应该用什么替换 sun.awt.shell.ShellFolder 这样我就不会收到编译警告?