获取 Infinispan 锁持有人线程

如何解决获取 Infinispan 锁持有人线程

我们的集群服务器应用程序具有相当古老的 Hibernate 和 Infinispan 依赖项:

org.hibernate:hibernate-core:4.3.8.Final
org.hibernate:hibernate-infinispan:4.3.8.Final
org.infinispan:infinispan-embedded:7.2.3.Final

不幸的是,我们在客户端请求线程上遇到了以下异常:

org.infinispan.util.concurrent.TimeoutException: ISPN000299: Unable to acquire lock after 180 seconds for key <myKey> and requestor GlobalTransaction:<cluster-main1-60783>:4480123069:local. Lock is held by GlobalTransaction:<cluster-main1-60783>:4479604524:local,while request came from local
    at org.infinispan.util.concurrent.locks.LockManagerImpl.lock(LockManagerImpl.java:198)
    at org.infinispan.util.concurrent.locks.LockManagerImpl.acquireLock(LockManagerImpl.java:171)
    at org.infinispan.interceptors.locking.AbstractTxLockingInterceptor.lockKeyAndCheckOwnership(AbstractTxLockingInterceptor.java:183)
    at org.infinispan.interceptors.locking.AbstractTxLockingInterceptor.lockAndRegisterBackupLock(AbstractTxLockingInterceptor.java:116)
    at org.infinispan.interceptors.locking.OptimisticLockingInterceptor.acquireAllLocks(OptimisticLockingInterceptor.java:253)
    at org.infinispan.interceptors.locking.OptimisticLockingInterceptor.visitPrepareCommand(OptimisticLockingInterceptor.java:88)
    at org.infinispan.commands.tx.PrepareCommand.acceptVisitor(PrepareCommand.java:123)
    at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:97)
    at org.infinispan.interceptors.NotificationInterceptor.visitPrepareCommand(NotificationInterceptor.java:36)
    at org.infinispan.commands.tx.PrepareCommand.acceptVisitor(PrepareCommand.java:123)
    at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:97)
    at org.infinispan.interceptors.TxInterceptor.invokeNextInterceptorAndVerifyTransaction(TxInterceptor.java:138)
    at org.infinispan.interceptors.TxInterceptor.visitPrepareCommand(TxInterceptor.java:125)
    at org.infinispan.commands.tx.PrepareCommand.acceptVisitor(PrepareCommand.java:123)
    at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:97)
    at org.infinispan.interceptors.base.CommandInterceptor.handleDefault(CommandInterceptor.java:111)
    at org.infinispan.commands.AbstractVisitor.visitPrepareCommand(AbstractVisitor.java:123)
    at org.infinispan.commands.tx.PrepareCommand.acceptVisitor(PrepareCommand.java:123)
    at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:97)
    at org.infinispan.interceptors.InvocationContextInterceptor.handleAll(InvocationContextInterceptor.java:102)
    at org.infinispan.interceptors.InvocationContextInterceptor.handleDefault(InvocationContextInterceptor.java:71)
    at org.infinispan.commands.AbstractVisitor.visitPrepareCommand(AbstractVisitor.java:123)
    at org.infinispan.commands.tx.PrepareCommand.acceptVisitor(PrepareCommand.java:123)
    at org.infinispan.interceptors.InterceptorChain.invoke(InterceptorChain.java:336)
    at org.infinispan.transaction.impl.TransactionCoordinator.prepare(TransactionCoordinator.java:121)
    at org.infinispan.transaction.impl.TransactionCoordinator.prepare(TransactionCoordinator.java:104)
    at org.infinispan.transaction.synchronization.SynchronizationAdapter.beforeCompletion(SynchronizationAdapter.java:44)
    at bitronix.tm.BitronixTransaction.fireBeforeCompletionEvent(BitronixTransaction.java:543)
    at bitronix.tm.BitronixTransaction.commit(BitronixTransaction.java:241)
    at bitronix.tm.BitronixTransactionManager.commit(BitronixTransactionManager.java:183)
    at org.hibernate.engine.transaction.internal.jta.JtaTransaction.doCommit(JtaTransaction.java:152)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:180)
    ... 

有没有办法找出哪个线程持有获取的锁?

解决方法

Infinispan 锁应该在事务的发起者是远程节点时工作,或者当应用程序挂起事务并在另一个线程上恢复它时,所以锁与事务相关联,而不是与线程相关联。

因此,查找哪个线程启动了持有特定密钥的事务的唯一方法是提前启用跟踪日志记录,例如org.infinispan.util.concurrent.locks.LockManagerImpl

,

除了 Dan 的回答之外,我们还使用了类似于以下代码的内容来确定异常消息中的关键是什么以及我们应该寻找哪个缓存:

import org.infinispan.Cache;
import org.infinispan.cache.impl.CacheImpl;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.util.concurrent.locks.LockManager;
 
import java.util.Set;
import java.util.TreeSet;
 
EmbeddedCacheManager cacheManager = ...
 
setAccessibility(true);
StringBuilder result = new StringBuilder();
Set cacheNames = new TreeSet(cacheManager.getCacheNames());
for (String cacheName: cacheNames) {
    boolean createIfAbsent = false;
    Cache cache = cacheManager.getCache(cacheName,createIfAbsent);
    if (cache instanceof CacheImpl) {
        CacheImpl cacheImpl = (CacheImpl) cache;
        LockManager lockManager = cacheImpl.getLockManager();
        if (lockManager.getNumberOfLocksHeld() == 0) {
            continue;
        }
        result.append("cache: ").append(cacheName).append("\n");
        result.append(" held: ").append(lockManager.getNumberOfLocksHeld()).append("\n");
        result.append(" available: ").append(lockManager.getNumberOfLocksAvailable()).append("\n");
        result.append(" concurrency level: ").append(lockManager.getConcurrencyLevel()).append("\n");
        result.append(" lock container: ").append(lockManager.lockContainer.getClass()).append("\n");
        result.append(" ").append(lockManager.printLockInfo());
        result.append("\n\n");
    } else {
        result.append("cache: ").append(cacheName).append("\n");
        result.append(" unknown cache type (template?): ").append(cache).append("\n");
        result.append("\n\n");
    }
}
 
return result.toString();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?