基于Mongodb分布式锁怎么解决定时任务并发执行问题
今天主机评测网小编给大家分享一下基于Mongodb分布式锁怎么解决定时任务并发执行问题的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
前言
我们日常开发过程,会有一些定时任务的代码来统计一些系统运行数据,但是我们应用有需要部署多个实例,传统的通过配置文件来控制定时任务是否启动又太过繁琐,而且还经常出错,导致一些异常数据的产生
网上有很多分布式锁的实现方案,基于redis、zk、等有很多,但是我的就是一个用了mysql和mongo的小应用,不准备引入其他三方中间件来解决这个问题,撸一个简单的分布式锁来解决定时任务并发执行的问题,加锁操作的原子性和防死锁也都要支持,这里我使用mongodb写了AllInOne的工具类
All in one Code
先上代码
ponent@Slf4jpublicclassMongoDBLock{privatestaticfinalintDEFAULT_LOCK_TIMEOUT=30;//锁的默认超时时间,单位秒privateMongoTemplatemongoTemplate;privateintlockTimeout;publicMongoDBLock(MongoTemplatemongoTemplate){this.mongoTemplate=mongoTemplate;this.lockTimeout=DEFAULT_LOCK_TIMEOUT;}/***尝试获取分布式锁**@paramlockKey锁的key*@returntrue:获取锁成功,false:获取锁失败*/privatebooleanacquireLock(StringlockKey){LockDocumentdocument=newLockDocument();document.setId(lockKey);document.setExpireAt(Instant.ofEpochMilli(Instant.now().toEpochMilli()+lockTimeout*1000));try{mongoTemplate.insert(document);returntrue;}catch(Exceptione){}returnfalse;}/***释放分布式锁**@paramlockKey锁的key*/privatevoidreleaseLock(StringlockKey){Queryquery=newQuery(Criteria.where("key").is(lockKey));mongoTemplate.remove(query,LockDocument.class);log.info("程序执行成功,释放分布式锁,lockKey:{}",lockKey);}/***分布式锁入口方法,参数lockName为锁的名称,lockKey为需要加锁的key,执行完成后自动释放锁**@paramlockKey*@paramtask*@param<T>*@throwsException*/public<T>voidexecuteWithLock(StringlockKey,ITask<T>task)throwsException{booleanlocked=acquireLock(lockKey);if(locked){log.info("获取分布式锁成功,lockKey:{}",lockKey);try{task.execute();}finally{releaseLock(lockKey);}}else{log.warn("获取分布式锁失败,lockKey:{}",lockKey);thrownewAppException("获取分布式锁失败!");}}@Data@Document(collection="lock_collection")staticclassLockDocument{@IdprivateStringid;@Indexed(expireAfterSeconds=DEFAULT_LOCK_TIMEOUT)privateInstantexpireAt;}@FunctionalInterfacepublicinterfaceITask<T>{Texecute()throwsException;}}
调用示例
@ResourceMongoDBLockmongoDBLock;mongoDBLock.executeWithLock("key",()->{//dosomethingreturnnull;});
原理
使用key作为主键,利用mongodb的insert原子性保障LockDocument不会重复插入
LockDocument中expireAt字段利用的mongodb索引过期机制,解决死锁问题,这里设置超时时间是30秒,并在执行完成之后会主动释放锁
以上就是“基于Mongodb分布式锁怎么解决定时任务并发执行问题”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注主机评测网行业资讯频道。
输入法切换键是哪个键?输入法切
冬月是哪一个月?冬月是什么意思
个人所得税退税金额怎么算出来的
输入法全角和半角有什么区别?输
a4纸尺寸是多少厘米?a4纸的由来
个人所得税扣除标准?个人所得税
输入法哪个好用?输入法介绍
卡拉OK是哪个国家发明的?卡拉OK
mikutools原神网页版入口链接?m
关机特别慢什么原因?电脑和手机