redisson简单使用-- 踩坑异常记录

2,530 阅读1分钟

记录下使用redisson的踩坑记录:

1. 解锁异常:attempt to unlock lock, not locked by current thread by node

在释放锁的时候,如果设置了持有锁的过期时间,当线程已经释放锁之后,再次调用解锁,则会提示此异常:

java.lang.IllegalMonitorStateException: attempt to unlock lock, not locked by current thread by node id: 60b15820-7321-4149-a60f-ffdb0552b82b thread-id: 230
	at org.redisson.RedissonLock.lambda$unlockAsync$3(RedissonLock.java:605)
	at org.redisson.misc.RedissonPromise.lambda$onComplete$0(RedissonPromise.java:187)
	at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:577)
	at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:551)
	at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:490)
	at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:615)
	at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:604)
	at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:104)
	at org.redisson.misc.RedissonPromise.trySuccess(RedissonPromise.java:82)
	at org.redisson.client.handler.CommandDecoder.completeResponse(CommandDecoder.java:451)
	at org.redisson.client.handler.CommandDecoder.handleResult(CommandDecoder.java:445)
	at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:376)
	at org.redisson.client.handler.CommandDecoder.decodeCommandBatch(CommandDecoder.java:265)
	at org.redisson.client.handler.CommandDecoder.decodeCommand(CommandDecoder.java:207)
	at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:134)
	at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:104)
	at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:498)
	at io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:366)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.lang.Thread.run(Thread.java:748)

翻到很多博客里面提到在finally里面释放锁,防止发生异常时出现死锁的现象。会直接使用 lock.unLock();

但是有一种情况:在finally里面释放锁的时候,如果锁已经释放了,再次调用lock.unLock();,则会抛出此异常。

保险的方法是,在释放前,判断下是否持有锁:lock.isLocked()

finally {
    if (lock.isLocked()){
        lock.unlock();
    }
}