(资料图片仅供参考)
前言我们日常开发过程,会有一些定时任务的代码来统计一些系统运行数据,但是我们应用有需要部署多个实例,传统的通过配置文件来控制定时任务是否启动又太过繁琐,而且还经常出错,导致一些异常数据的产生
网上有很多分布式锁的实现方案,基于redis、zk、等有很多,但是我的就是一个用了mysql和mongo的小应用,不准备引入其他三方中间件来解决这个问题,撸一个简单的分布式锁来解决定时任务并发执行的问题,加锁操作的原子性和防死锁也都要支持,这里我使用mongodb写了AllInOne的工具类
All in one Code先上代码
@Component@Slf4jpublic class MongoDBLock { private static final int DEFAULT_LOCK_TIMEOUT = 30;//锁的默认超时时间,单位秒 private MongoTemplate mongoTemplate; private int lockTimeout; public MongoDBLock(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; this.lockTimeout = DEFAULT_LOCK_TIMEOUT; } /** * 尝试获取分布式锁 * * @param lockKey 锁的key * @return true:获取锁成功,false:获取锁失败 */ private boolean acquireLock(String lockKey) { LockDocument document = new LockDocument(); document.setId(lockKey); document.setExpireAt(Instant.ofEpochMilli(Instant.now().toEpochMilli() + lockTimeout * 1000)); try { mongoTemplate.insert(document); return true; } catch (Exception e) { } return false; } /** * 释放分布式锁 * * @param lockKey 锁的key */ private void releaseLock(String lockKey) { Query query = new Query(Criteria.where("key").is(lockKey)); mongoTemplate.remove(query, LockDocument.class); log.info("程序执行成功,释放分布式锁,lockKey:{}",lockKey); } /** * 分布式锁入口方法,参数lockName为锁的名称,lockKey为需要加锁的key,执行完成后自动释放锁 * * @param lockKey * @param task * @param * @throws Exception */ public void executeWithLock(String lockKey, ITask task) throws Exception { boolean locked = acquireLock(lockKey); if (locked) { log.info("获取分布式锁成功,lockKey:{}",lockKey); try { task.execute(); } finally { releaseLock(lockKey); } } else { log.warn("获取分布式锁失败,lockKey:{}", lockKey); throw new AppException("获取分布式锁失败!"); } } @Data @Document(collection = "lock_collection") static class LockDocument { @Id private String id; @Indexed(expireAfterSeconds = DEFAULT_LOCK_TIMEOUT) private Instant expireAt; } @FunctionalInterface public interface ITask { T execute() throws Exception; }}
调用示例
@Resource MongoDBLock mongoDBLock; mongoDBLock.executeWithLock("key", () -> { // do some thing return null; });
原理使用key作为主键,利用mongodb的insert原子性保障LockDocument不会重复插入LockDocument中expireAt字段利用的mongodb索引过期机制,解决死锁问题,这里设置超时时间是30秒,并在执行完成之后会主动释放锁
前言我们日常开发过程,会有一些定时任务的代码来统计一些系统运行...
》》》天津通莎长途客运中心站五一购票重要通知为便于旅客在“五一...
马斯克经常有惊人之举,这是被外界广泛认知的。面对推特的整合是这...
今天来聊聊关于腹股沟疼痛是怎么回事,腹股沟疼痛的文章,现在就为...
1、战国时候,秦国最强,常常进攻别的国家。2、有一回,赵王得了一...
当地时间4月18日上午,苏丹快速支援部队宣布同意临时停火24小时,但...
Apple的无线耳机在移动行业引入了另一种趋势。AirPods的流行导致其...
1、CAD教育版打印时边框会有教育版的戳印。2、而正式版没有。3、用...
有一个成语“洗尽铅华”,从字面上来看,是把铅华都洗干净,洗掉,...
近日,贵州省产业大招商工作领导小组办公室通报了2022年度全省产业...
近期,天阳科技(300872)研发并申报的《一种可定制的流程作业开发系...
央视网消息:据国家统计局网站消息,3月份,社会消费品零售总额3785...
“截至2023年一季度末,浙商银行经济周期弱敏感资产的营收占比为30...
2023年4月18日,台湾食药署发布边境查验不合格食品名单,其中不合格...
4月18日,在财政部一季度财政收支发布会上,财政部有关负责人表示,...
湖北全民健身——农耕技能大比武---4月17日,参赛选手在池塘抓鱼比...
一个离婚案件中涉及男方婚前的股票和基金,这部分投资理财产品及婚...
近日,太原北代铸造有限公司将一面印有“为企业排忧解难做人民满意...
本田正在开发比传统电池更轻的低成本下一代太阳能电池。目标是到203...
4月17日北向资金减持68 75万股北汽蓝谷。近5个交易日中,获北向资...
陶土(粘土,或烤土)花盆的用途远不止于种花。工匠们使用方便的花...
4月17日,一段“物业经理带保安上门打业主”的视频引发关注。江苏省...
1、补骨脂是一种豆科植物,一般产于云南和四川但呢个低,这种植物的...
今天来聊聊关于关于古诗的作文题目自拟,关于古诗的作文的文章,现...
针对长江鲟高度濒危的现状,近年来,农业农村部组织有关科研单位全...
在对有可比数据的基金整理之后可以发现,一季度不论是市场份额增加...
1、首先,感冒以我个人经验只要不高于38 5度的患者是不用太着急去...
不久前据第三方数据显示,2023年比亚迪品牌累计上险量达到了357278...
1、网盘有很多噢,有收费的,有免费的。2、有大容量的,有小点容量...
除沧海芯片外,腾讯自研的AI推理芯片”紫霄“,采用自研存算架构和...