目录前言All in one Code原理前言 我们日常开发过程,会有一些定时任务的代码来统计一些系统运行数据,但是我们应用有需要部署多个实例,传统的通过配置文件来控制定时任务是否启动又太过繁琐,而且还经常出错,导致一些
我们日常开发过程,会有一些定时任务的代码来统计一些系统运行数据,但是我们应用有需要部署多个实例,传统的通过配置文件来控制定时任务是否启动又太过繁琐,而且还经常出错,导致一些异常数据的产生
网上有很多分布式锁的实现方案,基于Redis、zk、等有很多,但是我的就是一个用了Mysql和monGo的小应用,不准备引入其他三方中间件来解决这个问题,撸一个简单的分布式锁来解决定时任务并发执行的问题,加锁操作的原子性和防死锁也都要支持,这里我使用mongoDB写了AllInOne的工具类
先上代码
@Component
@Slf4j
public 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;
}
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;
}
private void releaseLock(String lockKey) {
Query query = new Query(Criteria.where("key").is(lockKey));
mongoTemplate.remove(query, LockDocument.class);
log.info("程序执行成功,释放分布式锁,lockKey:{}",lockKey);
}
public <T> void executeWithLock(String lockKey, ITask<T> 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> {
T execute() throws Exception;
}
}
调用示例
@Resource
MongoDBLock mongoDBLock;
mongoDBLock.executeWithLock("key", () -> {
// do some thing
return null;
});
到此这篇关于基于Mongodb分布式锁简单实现,解决定时任务并发执行问题的文章就介绍到这了,更多相关Mongodb分布式锁内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
--结束END--
本文标题: 基于Mongodb分布式锁解决定时任务并发执行问题
本文链接: https://lsjlt.com/news/201714.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-10-23
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0