我假设两个Realm交易不会互相干扰,因为交易是对的?但鉴于我不是数据库/ Realm专家,我需要对此进行确认,以便我可以尽快处理项目的其他部分。
我正在为失败的HTTP请求创建后台up-loader。每个请求在Realm中都有一个类,其对象是该类型的失败请求。还有一个名为“RequestUploadStatus”的类,它有一个名为“needsUpload”的字段,其对象维护给定的请求类是否包含需要上载的对象。
e.g。
评论
12,“你好”
45,“漂亮的上衣”
图片
无
RequestUploadStatus
[CommentClassId],真实的
[ImageClassId]。假
我不确定这是否是最好的方法,但现在让我们假设它是。
所以,我想避免的(假设存在多个线程)正在为具有错误'needsUpload'值的请求类之一提供RequestUploadStatus,例如,如果没有要上载的对象,则为true;如果有要上载的对象,则为false。因此,更具体地给出以下代码:如果上载事务正在循环通过RealmResults,则 schedule 事务被阻止添加要上载的新对象并为此设置'needsUpload'请求类。
安排交易
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
EntityUploadStatus entityUploadStatus = realm.where(EntityUploadStatus.class).equalTo("entityId", entityClassIdMap.entityId).findFirst();
entityUploadStatus.uploadNeeded = true;
//a comment or image or whatever
realm.insertOrUpdate(entity);
}
});
上传交易
realmInstance.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
RealmResults<RealmObject> realmObjects = realmInstance.where(realmClass).findAll();
for(int i = 0; i < realmObjects.size(); i++) {
RealmObject realmObject = realmObjects.get(i);
Boolean success = uploadObject(realmObject, classToUpload.entityId);
if(success)
{
realmObject.deleteFromRealm();
if (i == realmObjects.size())
{
//last one successfully uploaded, set status to uploaded
EntityUploadStatus entityUploadStatus = realm.where(EntityUploadStatus.class).equalTo("entityId", entityClassIdMap.entityId).findFirst();
entityUploadStatus.uploadNeeded = false;
}
}
else
break;
}
}
});
代码未经过测试,可能甚至无法编译,但您明白了我的想法。
答案 0 :(得分:2)
此答案适用于低于0.88.3且高于3.0.0的任何版本。
您目前的主张有一个主要问题:
realmInstance.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
RealmResults<RealmObject> realmObjects = realmInstance.where(realmClass).findAll();
for(int i = 0; i < realmObjects.size(); i++) { // <-- !!!
RealmObject realmObject = realmObjects.get(i);
Boolean success = uploadObject(realmObject, classToUpload.entityId);
if(success) {
realmObject.deleteFromRealm(); // <-- !!!
在交易中,您看到的RealmResults
始终是最新版本,包括您修改结果集元素的所有更改。
在这种情况下,您在使用简单循环直接迭代结果时删除项目:这意味着您将跳过元素,因为即使删除项目也会增加索引(并且基础结果集具有该项目)移除)!
所以你应该这样做:
RealmResults<RealmObject> realmObjects = realmInstance.where(realmClass).findAll();
for(RealmObject obj : realmObjects) { // 3.0.0+
或
RealmResults<RealmObject> realmObjects = realmInstance.where(realmClass).findAll();
for(int i = realmObjects.size() - 1; i >= 0; i--) { // 0.88.3 and below
或
RealmResults<RealmObject> realmObjects = realmInstance.where(realmClass).findAll();
OrderedRealmCollection<RealmObject> snapshot = realmObjects.createSnapshot(); // <-- !!!
for(int i = 0; i < snapshot.size(); i++) { // <-- !!!
RealmObject realmObject = snapshot.get(i);
无论如何,事务跨越线程阻塞,并且跨进程(2.0.0+),在给定时间只能打开一个打开的写事务。
因此,交易无法读取/操作无效/过期数据。