首页 > 数据库 >Redission并发锁报错:IllegalMonitorStateException: attempt to unlock lock, not locked by current thread by

Redission并发锁报错:IllegalMonitorStateException: attempt to unlock lock, not locked by current thread by

时间:2023-10-18 14:57:40浏览次数:34  
标签:node attempt lock unlock 报错 CommandBatchService CompletableFuture id

生产上突然出现一条报错

    j.l.IllegalMonitorStateException: attempt to unlock lock, not locked by current thread by node id: 1411e030-3c44-48d7-9eb6-6030022ce681 thread-id: 111
    at o.r.RedissonBaseLock.lambda$unlockAsync$2(RedissonBaseLock.java:323)
    at j.u.c.CompletableFuture.uniHandle(CompletableFuture.java:930)
    at j.u.c.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:907)
    at j.u.c.CompletableFuture.postComplete(CompletableFuture.java:506)
    at j.u.c.CompletableFuture.complete(CompletableFuture.java:2073)
    at o.r.c.CommandBatchService.lambda$executeAsync$7(CommandBatchService.java:322)

先看下报错地方使用到的代码如下

RLock lock = redissonClient.getLock(key);
if (lock.tryLock()) {
    try {
       //业务代码
    }finally {
        lock.unlock();
    }
} else {
     // 其余处理
}        

这个是方法说明中推荐的用法了

    /**
     * Acquires the lock only if it is free at the time of invocation.
     *
     * <p>Acquires the lock if it is available and returns immediately
     * with the value {@code true}.
     * If the lock is not available then this method will return
     * immediately with the value {@code false}.
     *
     * <p>A typical usage idiom for this method would be:
     * <pre> {@code
     * Lock lock = ...;
     * if (lock.tryLock()) {
     *   try {
     *     // manipulate protected state
     *   } finally {
     *     lock.unlock();
     *   }
     * } else {
     *   // perform alternative actions
     * }}</pre>
     *
     * This usage ensures that the lock is unlocked if it was acquired, and
     * doesn't try to unlock if the lock was not acquired.
     *
     * @return {@code true} if the lock was acquired and
     *         {@code false} otherwise
     */
    boolean tryLock();

查看报错的tracing日志,unlock之前的操作时间很短,只有200ms左右,不存在锁超时自动释放的情况,百思不得其解。

在网上查了很多相关报错的记录,一些比如“建议unlock之前先检查一下当前线程是否持有锁”来避免报错,都未根本性地描述问题原因和解决办法。

 

排查的思路如下:

先去了Redisson的官网(https://github.com/redisson/redisson/wiki/8.-distributed-locks-and-synchronizers/#81-lock)查看了一下锁相关的说明,未找到需要的信息

然后去issus内搜索关键词,终于找到了遇到同样问题的人,并且看到了最近已经修复的提示(写本篇的时候还为发布到预计发布的3.23.6中):

1. 问题描述:https://github.com/redisson/redisson/issues/4871

2. 修复代码改动:https://github.com/redisson/redisson/commit/22c239eaf8b46c8d0e94af14c98ced21bdee0b52#diff-589deed8cc0d31690d8a3b1d16b81c366fa8b9346969295df2061d610fa166b3

    protected final RFuture<Boolean> unlockInnerAsync(long threadId) {
        String id = getServiceManager().generateId();
        MasterSlaveServersConfig config = getServiceManager().getConfig();
        int timeout = (config.getTimeout() + config.getRetryInterval()) * config.getRetryAttempts();
        RFuture<Boolean> r = unlockInnerAsync(threadId, id, timeout);
        CompletionStage<Boolean> ff = r.thenApply(v -> {
            //commandExecutor.writeAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.DEL, getUnlockLatchName(id)); 这个是被删除的代码
       //以下为新增代码
            CommandAsyncExecutor ce = commandExecutor;
            if (ce instanceof CommandBatchService) {
                ce = new CommandBatchService(commandExecutor);
            }
            ce.writeAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.DEL, getUnlockLatchName(id));
            if (ce instanceof CommandBatchService) {
                ((CommandBatchService) ce).executeAsync();
            }
       //新增代码结束位置
            return v;
        });
        return new CompletableFutureWrapper<>(ff);
    }

看起来是显示地使用了CommandBatchService这个用来批量操作Redis命令的服务,不过因为本身对整体源码还不熟,一时也看不懂造成报错的根本原因是什么。

这里先存个疑,计划要了解的如下:

1. 分布式锁存在Redis内的格式是怎么样的?

2. 加锁和解锁的流程是怎么样的?

3. 如何保证的数据一致性呢?

4. 高并发情况下有什么需要注意点?

 

标签:node,attempt,lock,unlock,报错,CommandBatchService,CompletableFuture,id
From: https://www.cnblogs.com/longmmeng/p/17772326.html

相关文章

  • Node.js 21 版本已发布!
    本文翻译自Node.js21isnowavailable!,来源:TheNode.jsProject,略有删改。我们很高兴地宣布Node.js21的发布!亮点包括V8JavaScript引擎更新到11.8,稳定fetch和WebStreams,一个新的实验性标志来切换模块默认值(--experimental-default-type),一个内置的WebSocket客户端,我们的测......
  • 【git】git pull更新项目报错git error:invalid path
    1、报错内容error:invalidpath'xxxxxxx'原因是某分支下的文件名格式不支持,最终导致在gitclone的时候找不到这个文件路径导致的! 2、解决方法gitconfigcore.protectNTFSfalse作用是关掉NTFS下的路径保护机制,防止文件系统出错,这样就不存在找不到文件路径了......
  • 【Python入门教程】CV2报错:cv2.error: OpenCV(4.7.0) D:\a\opencv-python\opencv-p
    ​     OpenCV作为一个强大计算机视觉库被各个领域广泛应用,今天分享下自己编程遇到的报错信息以及解决办法。1报错信息​[WARN:[email protected]]globalgrfmt_tiff.cpp:716cv::TiffDecoder::readDataOpenCVTIFF:TIFFRGBAImageOK:Sorry,cannothandleimageswith6......
  • pino 一个很不错的node log 框架
    pino是一个很不错的nodejs日志框架,fastify就集成了此框架,而且提供了不少框架的扩展,可以方便集成(express,koa,nest,hapi。。。)参考使用app.jsconstpino=require('pino')constlogger=pino({timestamp:pino.stdTimeFunctions.isoTime,})logger.in......
  • 谷歌浏览器崩溃报错:STATUS_INVALID_IMAGE_HASH
    【1】问题谷歌浏览器崩溃,Edge浏览器也无法访问任何网页 【2】解决办法(2.1)方法1:直接运行脚本修复新建文本文档,重命名为.reg修改其内容为:WindowsRegistryEditorVersion5.00[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome]"RendererCodeIntegrityEnabled"=......
  • docker部署elasticsearch 遇到FileSystemException 报错
    Exceptioninthread"main"java.nio.file.:/usr/share/elasticsearch/config/elasticsearch.yml.vxt5sWMES_eRFvPQPfckLQ.tmp->/usr/share/elasticsearch/config/elasticsearch.yml:Deviceorresourcebusy atjava.base/sun.nio.fs.UnixException.trans......
  • Node.js框架:通过nvm实现多个node版本共存使用
    一、环境部署1、nvm下载下载地址:https://github.com/coreybutler/nvm-windows/releases2、nvm安装打开安装程序后按流程走就行,中间的安装地址可以自定义调整。注:在选择node.js的路径时,默认路径为C盘里的安装路径,如果本地在该路径下已经安装过......
  • sqlplus本地登录报错,远程可以正常登录
    问题描述:  sqlplus本地登录报错,如下:   sqlplus/asssydba   ERROR:   ORA-12547:TNS:lostcontact原因分析:   首先确保数据库实例正常运行:   srvctlstatusdatabase-dDB_UNIQUE_NAME   ps-ef|greppmon    查看ORACLE_H......
  • python报错解决-ValueError: Trusted host URL must include a host part: '#!
    删掉#后面的字符参考:pipinstall总是报错:ValueError:TrustedhostURLmustincludeahostpart:‘#‘-CSDN博客......
  • 【Azure Logic App】使用Outlook.com发送邮件遇到429报错
    问题描述在LogicApp中使用Outlook.com组件发送邮件,遇见了outlookconnection报429的错误{"error":{"code":"ErrorExceededMessageLimit","message":"Cannotsendmail.DailyMessage/Recipientlimitexceeded.Followtheinstructionsinyo......