这两个Realm交易是否会相互干扰

时间:2017-10-26 16:45:09

标签: android realm

我假设两个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;


                                }

                            }
                        });

代码未经过测试,可能甚至无法编译,但您明白了我的想法。

1 个答案:

答案 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+),在给定时间只能打开一个打开的写事务。

因此,交易无法读取/操作无效/过期数据。