并发修改不应该被记录为ERROR?

问题描述 投票:0回答:1

我们有一个应用程序运行在Wildfly 17上。我有一个偶尔发生的场景,其中两个后台线程正在访问同一个实体。

  • 线程A删除了实体(理由充分)。
  • 线程B正在处理稍旧的数据,并试图更新实体。

当线程B是两个线程中的后来者时,由于并发修改而失败。这样做是正确的。它会自动重试,并发现不需要再做什么(因为实体已经被删除)。这就是预期的行为,当这两个线程相撞时。一切都很好!

然而,我发现这被记录为ERROR。CMTTxInterceptor:

2020-03-31 16:51:35,463 +0200 ERROR: as.ejb3.invocation - WFLYEJB0034: EJB Invocation failed on component ... for method ... throws ...: 
  javax.ejb.EJBTransactionRolledbackException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:203) [wildfly-ejb3-17.0.1.Final.jar:17.0.1.Final]
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:364) [wildfly-ejb3-17.0.1.Final.jar:17.0.1.Final]
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:144) [wildfly-ejb3-17.0.1.Final.jar:17.0.1.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
...
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [rt.jar:1.8.0_171]
    at org.apache.activemq.artemis.utils.ActiveMQThreadFactory$1.run(ActiveMQThreadFactory.java:118)
Caused by: javax.persistence.OptimisticLockException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.wrapStaleStateException(AbstractEntityManagerImpl.java:1729) [hibernate-entitymanager.jar:5.0.12.Final]
... at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:185) [wildfly-ejb3-17.0.1.Final.jar:17.0.1.Final]
    ... 262 more
Caused by: org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
    at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:67) [hibernate-core.jar:5.0.12.Final]
    at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:54) [hibernate-core.jar:5.0.12.Final]
    at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:46) [hibernate-core.jar:5.0.12.Final]
    at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3261) [hibernate-core.jar:5.0.12.Final]
...

在我看来,这个日志是不正确的,主要是因为这不是一个错误。并发的修改是正常的,是可以预料到的--我们的应用逻辑可以处理。这个日志会让我的热线同事分心。

您是否同意这个日志是不正确的,还是我遗漏了什么?

我想我会禁用 "as.ejb3.invocation "的日志记录。

wildfly ejb-3.0 error-logging concurrentmodification
1个回答
0
投票

在你的案例中,之所以抛出这个异常,是因为Hibernate检测到之前从数据库获取的实体在当前事务中被更改(删除)。所以,没有什么可以更新的。

在这种特殊情况下,我认为你可以忽略或吞下这个异常。在其他情况下,知道这个异常可能是好事,所以我建议吞掉这个异常,但不要在日志级别上整体禁用。

© www.soinside.com 2019 - 2024. All rights reserved.