hibernate - org.infinispan.util.concurrent.TimeoutException:ISPN000299:15 秒后无法获取密钥
问题描述
我对 Hibernate L2 缓存有以下问题:
线程 1
- 执行本机查询:DELETE ... FROM WHERE ... => 整个 L2 缓存失效
- 长流程运行
线程 2
- 执行本机查询:UPDATE SET ... WHERE ... => 整个 L2 缓存失效
- 线程被线程 1 阻塞
- 15 秒后,ISPN000299 升高。
这是完整的堆栈跟踪:
2020-03-11 15:06:01,384 ERROR [InvocationContextInterceptor] ISPN000136: Error executing command RemoveCommand, writing keys [com.sylob.cochise.dm1.ejb.entite.plageHoraire.PlageHoraireCoreEntite#4028ae256b033913016b0342b7ed6229]: org.infinispan.util.concurrent.TimeoutException: ISPN000299: Unable to acquire lock after 15 seconds for key com.sylob.cochise.dm1.ejb.entite.plageHoraire.PlageHoraireCoreEntite#4028ae256b033913016b0342b7ed6229 and requestor GlobalTransaction:<null>:1485:local. Lock is held by GlobalTransaction:<null>:1402:local
at org.infinispan.util.concurrent.locks.impl.DefaultLockManager$KeyAwareExtendedLockPromise.lock(DefaultLockManager.java:238)
at org.infinispan.interceptors.locking.AbstractLockingInterceptor.lockAndRecord(AbstractLockingInterceptor.java:193)
at org.infinispan.interceptors.locking.AbstractTxLockingInterceptor.checkPendingAndLockKey(AbstractTxLockingInterceptor.java:193)
at org.infinispan.interceptors.locking.AbstractTxLockingInterceptor.lockOrRegisterBackupLock(AbstractTxLockingInterceptor.java:116)
at org.infinispan.interceptors.locking.PessimisticLockingInterceptor.visitDataWriteCommand(PessimisticLockingInterceptor.java:134)
at org.infinispan.interceptors.locking.AbstractLockingInterceptor.visitRemoveCommand(AbstractLockingInterceptor.java:75)
at org.infinispan.commands.write.RemoveCommand.acceptVisitor(RemoveCommand.java:67)
at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:99)
at org.infinispan.interceptors.TxInterceptor.enlistWriteAndInvokeNext(TxInterceptor.java:367)
at org.infinispan.interceptors.TxInterceptor.visitRemoveCommand(TxInterceptor.java:231)
at org.infinispan.commands.write.RemoveCommand.acceptVisitor(RemoveCommand.java:67)
at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:99)
at org.infinispan.interceptors.InvocationContextInterceptor.handleAll(InvocationContextInterceptor.java:114)
at org.infinispan.interceptors.InvocationContextInterceptor.handleDefault(InvocationContextInterceptor.java:83)
at org.infinispan.commands.AbstractVisitor.visitRemoveCommand(AbstractVisitor.java:48)
at org.infinispan.commands.write.RemoveCommand.acceptVisitor(RemoveCommand.java:67)
at org.infinispan.interceptors.InterceptorChain.invoke(InterceptorChain.java:335)
at org.infinispan.cache.impl.CacheImpl.executeCommandAndCommitIfNeeded(CacheImpl.java:1672)
at org.infinispan.cache.impl.CacheImpl.removeInternal(CacheImpl.java:557)
at org.infinispan.cache.impl.CacheImpl.remove(CacheImpl.java:549)
at org.infinispan.cache.impl.CacheImpl.remove(CacheImpl.java:543)
at org.infinispan.cache.impl.AbstractDelegatingCache.remove(AbstractDelegatingCache.java:296)
at org.hibernate.cache.infinispan.util.Caches.removeAll(Caches.java:285)
at org.hibernate.cache.infinispan.access.InvalidationCacheAccessDelegate.removeAll(InvalidationCacheAccessDelegate.java:149)
at org.hibernate.cache.infinispan.entity.ReadOnlyAccess.removeAll(ReadOnlyAccess.java:65)
at org.hibernate.action.internal.BulkOperationCleanupAction$EntityCleanup.<init>(BulkOperationCleanupAction.java:210)
at org.hibernate.action.internal.BulkOperationCleanupAction$EntityCleanup.<init>(BulkOperationCleanupAction.java:203)
at org.hibernate.action.internal.BulkOperationCleanupAction.<init>(BulkOperationCleanupAction.java:110)
at org.hibernate.engine.query.spi.NativeSQLQueryPlan.coordinateSharedCacheCleanup(NativeSQLQueryPlan.java:152)
at org.hibernate.engine.query.spi.NativeSQLQueryPlan.performExecuteUpdate(NativeSQLQueryPlan.java:176)
at org.hibernate.internal.SessionImpl.executeNativeUpdate(SessionImpl.java:1373)
at org.hibernate.internal.SQLQueryImpl.executeUpdate(SQLQueryImpl.java:373)
我正在使用 Hibernate 5.0.10.Final / Infinispan 8.2.4.Final 运行 Wildfly 10.1.0.Final(独立完整配置文件)。
环境不是集群的,会话也不是复制的。
我正在使用 Wildfly 为 Infinispan L2 缓存提供的默认配置:
<cache-container name="hibernate" default-cache="local-query" module="org.hibernate.infinispan">
<local-cache name="entity">
<transaction mode="NON_XA"/>
<eviction strategy="LRU" max-entries="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<local-cache name="local-query">
<eviction strategy="LRU" max-entries="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<local-cache name="timestamps"/>
</cache-container>
使用 Hibernate 3.x / EhCache,这曾经可以工作。
这里有什么问题?
任何支持表示赞赏...
解决方案
本机 SQL 批量更新会使整个 L2 缓存失效。这不是你想要的。所以你必须通过使用来告诉hibernate,例如:
query.unwrap(SQLQuery.class).addSynchronizedEntityClass(YourEntity.class).executeUpdate();
这应该避免使整个缓存失效。
另外,看看类 org.hibernate.action.internal.BulkOperationCleanupAction
参考:https ://www.baeldung.com/hibernate-second-level-cache 见第 10 项。
推荐阅读
- php - WooCommerce - 通过送货方式在感谢页面上添加内容
- android - 当我为 Firestore 适配器输入空间时,Searchview 不起作用
- javascript - 在 XMLHttpRequest 开始和结束之间循环 JavaScript
- javascript - 我应该打电话给 preventDefault 吗?如何获取默认操作的用户代理列表?
- asp.net - IIS 10 没有为会话状态设置 Asp.Net cookie
- java - 即使将 cplex.jar 添加到 lib 后,包 ilog 也不存在
- python - 如何通过dict中的匹配使硒单击部分链接文本
- android - Android WorkManager 没有启动工作人员
- driver - 安装未绑定的 NDIS 文件管理器驱动程序
- php - 将变量传递给函数时出现 500 错误