wildfly - 并发修改不应记录为错误?
问题描述
我们有一个在 Wildfly 17 上运行的应用程序。我有一个场景,偶尔会发生,其中两个后台线程正在访问同一个实体:
- 线程 A 删除实体(有充分理由)
- 线程 B 正在处理稍旧的数据并尝试更新实体
当线程 B 是两者中的后者时,由于并发修改而失败。这可以正常工作。它会自动重试,发现不需要再做任何事情(因为实体已被删除)。当这两个线程发生冲突时,这是预期的行为。一切皆好!
但是我发现这被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”的日志记录。
解决方案
在您的情况下,抛出此异常是因为 Hibernate 检测到先前从数据库中获取的实体在当前事务期间已更改(删除)。所以,没有什么可更新的。
在这种特定情况下,我认为您可以忽略或吞下异常。在其他情况下,了解此异常可能会很好,因此我建议吞下异常,但不要在日志级别上将其作为一个整体禁用。
推荐阅读
- c# - 在场景之间访问 Firebase 用户/数据库?
- python - 我将如何在此代码中添加选项和附加功能
- javascript - How can I calculate the angle between two lines with the same starting point?
- c# - 如何从 bson 文档中的键获取值以放入 ListBox (C#)
- .net - 如何在不加载该程序集的情况下将 AssemblyName 解析为程序集文件路径?
- regex - 匹配所有正则表达式模式,直到达到分隔模式
- lua - Lua 错误尝试索引全局 nil 值
- ruby-on-rails - 错误:分支“升级”未完全合并
- image - 如何使用淡入淡出效果,如 CSS 过渡到 SVG 中的图像标签?
- tensorflow - 与普通层不同,Keras 自定义层不返回权重