如何从头实现乐观锁?

问题描述

我正在写入文件,并且我的工作量非常无争议。但是,出现竞争条件的可能性很小。我想在这个阶段避免使用数据库并自己在文件系统上实现乐观锁定。我该怎么办?

理想情况下,我只会写入文件系统并在写入时断言有关文件版本的一些先决条件,但我看不到任何用于执行此操作的 nodejs API。

我最初想做某种锁定的想法是我可以做某种时间戳锁定。

  1. 线程 A 和线程 B 都读取了最新版本
  2. 线程 A 写入版本 Timestamp1
  3. 线程 B 写了一个版本 Timestamp2
  4. 线程 A 和线程 B 等待线程 C 进行协调,线程 C 将查看自上一个最新版本以来是否编写了多个版本。如果是这样,是否会为该文件创建一个队列?

也许有更简单的方法来做到这一点?

注意:我打算用 nodejs 实现,所以线程不是实际的线程。它们可以是并发异步任务或事件不同的进程。我想避免使用互斥锁或内存队列,因为它们可能是不同的进程。

解决方法

这属于 file locking

虽然不是乐观锁,但一个常见的策略是利用这样一个事实,即在大多数文件系统上创建目录是有条件的写入,即如果已经存在,它将失败。因此可以使用 mkdir 获取锁。

const fs = require("fs");

const acquireLock = async (identifier,retries = 5,delay = 1000) => {
  const pathname = `${identifier}.lock`;
  const acquire = () => {
    try {
      fs.mkdirSync(pathname);
      return true;
    } catch {}
  };
  const release = () => fs.rmdirSync(pathname);
  for (let i = 0; i < retries; i++) {
    if (acquire()) return release;
    await new Promise((r) => setTimeout(r,delay));
  }
};
const usage = async () => {
  const lock = await acquireLock("asdf");
  if (lock) {
    console.log("got the lock!");
    lock();
  } else {
    console.log("failed to get the lock!");
  }
};

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...