2016-07-05 4 views
1

여러 스레드에서 RealmDB를 사용하는 것이 권장되는 방법인지 알고 싶습니다.여러 스레드에서 RealmDB에 액세스

내 시나리오 : 하나의 스레드를 사용하고 일부 작업을 수행하여 RealmDB의 레코드를 반복합니다. 이전 작업의 응답을 기반으로 다른 스레드에서 레코드를 제거하고 싶습니다.

이것을 달성하는 가장 좋은 방법은 무엇입니까?

답변

1

RealmObject 필드 값 (예 : id, primaryKey)을 스레드에 전달할 수 있습니다. 즉, 다른 스레드에서 "action1"을 완료하면 id를 스레드로 전송할 수 있습니다 영역 작업을 처리하고, 제거해야 할 객체를 쿼리하고 영역에서 객체를 삭제할 책임이있는 경우 Realm이 작동하는 스레드에서 더 이상 삭제 작업을 수행하기 위해 TransactionAsync를 실행할 수 있습니다. 영역 쓰기 작업에서

편집

  • 는 읽기 작업을 차단하지 않습니다. 당신은 또한 addChange 수신기를 사용할 수있는 관찰 가능한 사용하지 않을 경우 당신은 관찰 가능한 같은 읽기 작업을 사용하는 경우 우리가 영역 인스턴스를
  • 을 닫을 때까지
  • RealmResults & RealmObjects 라이브 객체, 모든 추가 수정이 통보됩니다.

는 몇 가지 코드를 살펴 가질 수 있습니다 :

당신이 영역의 인스턴스가 클래스 중 하나를 말할 수 있습니다, 그리고 당신은

realm.where(GitHubUser.class).findAll().asObservable() 
     .filter(RealmResults::isLoaded) 
     .filter(RealmResults::isValid) 
     .subscribeOn(AndroidSchedulers.mainThread()) 
     .observeOn(AndroidSchedulers.mainThread()) 
     .subscribe(gitHubUsers -> { 
      for (GitHubUser gitHubUser : gitHubUsers) { 
       Log.e("TAG", "data = " + gitHubUser.getLogin()); 
      } 
     }); 
(이 예에서는 mainThread) ThreadA 읽어 작업을하고있다

그리고 해당 addChangeListener 버전

RealmResults realmResults = realm.where(GitHubUser.class).findAll(); 
realmResults.addChangeListener(new RealmChangeListener<RealmResults>() { 
    @Override 
    public void onChange(RealmResults element) { 
     for (GitHubUser gitHubUser : gitHubUsers) { 
      Log.e("TAG", "data = " + gitHubUser.getLogin()); 
     } 
    } 
}); 

for (GitHubUser gitHubUser : gitHubUsers) { 
    Log.e("TAG", "data = " + gitHubUser.getLogin()); 
} 

와의 당신이 방아쇠를 얻고 ENTR 중 하나를 삭제하고 싶은 말은하자 y를 별도의 스레드에서 수행하려면, 새 Realm 인스턴스를 가져 와서 아래 표시된대로 항목을 삭제하고 Realm 인스턴스를 닫습니다. 이 방법을 사용하면 스레드 문제가 발생하지 않고 항목을 삭제 한 후 읽기 쿼리에 알림이 표시되고 업데이트 된 데이터로보기를 업데이트 할 수 있습니다.

new Thread(() -> { 
    Realm realm1 = Realm.getDefaultInstance(); 

    GitHubUser gitHubUser = realm1.where(GitHubUser.class) 
      .equalTo("login", "loginString") 
      .findFirst(); 

    if (gitHubUser != null) { 
     realm1.executeTransaction(realm2 -> gitHubUser.deleteFromRealm()); 
    } 
    realm1.close(); 
}).run(); 
+0

Viraj 외부 이벤트를 수신 할 때만 별도의 스레드에서 삭제를 수행해야하므로 executeTransactionAsync를 사용할 수 없습니다. 네가 언급 한 다른 해결책은 내 질문에 구체적으로 말한 것이있다. DB에 10 개의 레코드가있다. 스레드 A에서 루프를 돌고 있습니다. ThreadA에서 Record1을 게시하고 RecordB에 대한 ThreadB에서 응답을받는 것과 같은 시간에 게시합니다. 이제이 상황에서 스레드 A에서 레코드 2에서 10까지 반복하지만 스레드 B에서 Record1을 삭제해야합니다. 어떻게 안전하게 처리 할 수 ​​있습니까? – ATO

+0

@ATO 업데이트 된 답변을 찾으시고, 원하시는 것이 아닌지 알려주십시오. –

+0

감사합니다이게 나에게 좋은 해결책 인 것 같습니다. 이걸 시험해 보게. – ATO

관련 문제