我花了相当多的时间研究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
答案 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然后工作很简单,因为没有并发更新。