Realm是否支持SELECT FOR UPDATE样式读锁定

时间:2017-11-17 21:13:54

标签: realm

我花了相当多的时间研究Realm数据库机制,我无法弄清楚Realm是否在写入事务期间为引擎选择的数据使用行级读锁。

作为一个基本示例,想象一下以下“队列”逻辑

假设队列有任意数量的作业(我们将说5个作业)

 async getNextJob() {

    let nextJob = null;

    this.realm.write(() => {

      let jobs = this.realm.objects('Job')
        .filtered('active == FALSE')
        .sorted([['priority', true], ['created', false]]);

      if (jobs.length) {
        nextJob = jobs[0];
        nextJob.active = true;
      }

    });

    return nextJob;

  }

如果我同时调用getNextJob()2次,如果没有发生行级读取阻塞,则当我们查询作业时,nextJob可能会返回相同的作业对象。

此外,如果我的外部逻辑依赖于读取逻辑中的最新数据(例如,当当前实际为真时,job.active == false)我需要阻止读取直到更新事务完成。 MVCC读取过时数据在这种情况下不起作用。

如果在写入事务中设置读锁定,我可以确保我总是读取最新数据

let active = null;
this.realm.write(() => {

  const job = this.realm.pseudoQueryToGetJobByPrimaryKey();
  active = job.active;

});

// Assuming the above write transaction blocked the read until 
// any concurrent updates touching the same job committed
// the value for active can be trusted at this point in time.
if (active === false) {
  // code to start job here
}

基本上,TL; DR是否支持SELECT FOR UPDATE?

PostgreSQL的

https://www.postgresql.org/docs/9.1/static/explicit-locking.html

MySql

https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html

2 个答案:

答案 0 :(得分:1)

  

基本上,TL; DR是否支持SELECT FOR UPDATE?

如果我正确地理解了这个问题,那么答案就会比那更棘手。

如果没有涉及Realm Object Server,则realm.write(() =>不允许同时进行任何其他写入,并在事务打开时将Realm更新为其最新版本。

如果涉及Realm Object Server,那么我认为它仍然在本地,但Realm Sync管理来自远程的更新,在这种情况下,冲突解决规则适用于远程数据更改。

答案 1 :(得分:0)

Realm不允许并发写入。最多只有一个正在进行中 在任何时间点写交易。

如果异步getNextJob()函数同时调用两次,则其中一个 调用将在realm.write()上阻止。

SELECT FOR UPDATE然后工作很简单,因为没有并发更新。