2016-09-14 5 views
0

Мне просто интересно, является ли то, что я делаю для обновления всей таблицы в области, является правильным безопасным подходом. Я получаю список разговоров с сервера и обновить БД так:Обновить таблицу в реальном времени

@Override 
public void saveConversations(final List<Conversation> conversations) { 
    realm.executeTransactionAsync(new Realm.Transaction() { 
     @Override 
     public void execute(Realm realm) { 

      // Remove all conversations and replace with the one passed in 
      // Realm does not support cascade deletes. Remove messages as well 
      // https://github.com/realm/realm-java/issues/1104 
      realm.delete(Conversation.class); 
      realm.delete(Message.class); 

      realm.copyToRealmOrUpdate(conversations); 
     } 
    }); 
} 

Conversation.java имеет RealmList сообщений внутри:

public class Conversation extends RealmObject { 

    private RealmList<Message> messages = new RealmList<>(); 

Это работает, я не мог найти какие-либо ошибки с ним, но это выглядит не очень элегантно. Что делать, если realm.copyToRealmOrUpdate(conversations); идет не так? Я потеряю все свои данные.

В любом случае, я знаю, что это не очень вероятно, но мне было интересно, есть ли лучший способ делать что-то.

PS: Имейте в виду, что я удаляю все из db, потому что мне больше не нужны разговоры в моем db, которые больше не существуют на сервере.

ответ

0

Не забывайте, что вы выполняете транзакцию, поэтому, если copyToRealmOrUpdate() не работает, транзакция отменена, что означает, что вы не потеряете все свои данные.

Лично я использовал подход «удалить все», и если вы можете очистить все таблицы, это не вызовет проблем, но если у вас есть третья таблица, в которой вы ссылаетесь на Conversation и Message (например, User.class), вы бы признали недействительными все отношения. Поэтому я лично предпочитаю сливаться вот так.

  • объединение данных и удаление всех данных, которые не в списке, вы экономии

.

public class Contact { 
    @PrimaryKey 
    private long id; 

    @Index 
    private String name; 

    @Index 
    private String phoneNumber; 

    @Index 
    private boolean isBeingSaved; // this line is important 

    //getters, setters 
} 

Затем слить:

// background thread 
Realm realm = null; 
try { 
    realm = Realm.getDefaultInstance(); 
    final List<Contact> contacts = getContacts(); 
    realm.executeTransaction(new Realm.Transaction() { 
     @Override 
     public void execute(Realm realm) { 
      realm.insertOrUpdate(contacts); 
      realm.where(Contact.class) 
       .equalTo(ContactFields.IS_BEING_SAVED, false) // compile 'dk.ilios:realmfieldnameshelper:1.1.0' 
       .findAll() 
       .deleteAllFromRealm(); // delete all non-saved data 
         // in your case, this is where you'd handle the cascading too though manually 
      for(Contact realmContact : realm.where(Contact.class).findAll()) { // realm 0.89.0+ 
       realmContact.setIsBeingSaved(false); // reset all save state 
      } 
     } 
    }); 
} finally { 
    if(realm != null) { 
     realm.close(); 
    } 
} 
+0

не было известно сделка будет возвращены, если это не удастся, это довольно интересная особенность. Спасибо вам за использование вашего подхода1 – feresr

+0

Да, это то, что делает 'executeTransaction()', иначе это будет вручную 'realm.beginTransaction()', 'realm.commitTransaction()' и 'realm.cancelTransaction()'. Примеры часто игнорируют «realm.cancelTransaction()» при ошибке, несмотря на то, что очень важно отменить транзакцию записи при сбое. – EpicPandaForce

Смежные вопросы