-
[Swift] Realm 스레딩 이용시 주의사항 - Realm은 하나의 스레드에서 작업이 이루어져야 한다code 2023. 3. 17. 02:02
Realm은 하나의 스레드에서 작업이 이루어져야 한다.
: Realm은 데이터베이스의 동시성 이슈를 제어하기 위한 데이터베이스이다.
= 멀티 버전 동시성 제어(MVCC)
= 연결되는 스레드는 특정한 시점의 데이터 스냅샷을 보게 된다.
(= 일반적인 경우 가장 최신 버전)
Relam의 객체는 자동 갱신된다.
let puppies = realm.objects(Dog).filter("age < 2") puppies.count // => 아직 개가 Realm에 추가되지 않았기 때문에 0 let myDog = Dog() myDog.name = "Rex" myDog.age = 1 try! realm.write { realm.add(myDog) } puppies.count // => 실시간으로 1로 갱신됩니다. // 다른 질의에서 개에 접근합니다 let puppy = realm.objects(Dog).filter("age == 1").first try! realm.write { puppy.age = 3 } // 원래 개 객체는 자동 갱신됩니다. myDog.age // => 3 puppies.count // => 0 // 출처: https://academy.realm.io/kr/posts/threading-deep-dive/
다른 질의에서 변경되더라도 원래의 Dog 인스턴스는 자동으로 갱신된다.
자동으로 갱신되면 변경 되었는지 어떻게 알 수 있는지?
[자동 갱신 기능에 대해 Realm 변경 노티피케이션 받기]
// Observe Realm Notifications let token = realm.observe { notification, realm in viewController.updateUI() } // later token.invalidate() //출처: https://www.mongodb.com/docs/legacy/realm/swift/latest/#notifications
Thread-Safe Model
: Realm은 스레드 경계를 넘지 못한다.
Realm이 스레드를 넘어서 객체를 전달하면 확정되지 않은 시점에 데이터 수정을 시도할 수 있다.
-> 경쟁상황, 같은 시점에 여러개의 스레드에서 하나의 메모리에 동시에 접근하는 문제 (Race Condition)
데이터 일관성을 지키기 힘들어진다.
일반적인 DB 경우에는 변경자 접근자에 락을 걸지만, Realm은 속도와 데이터 일관성 보장을 위해 락을 사용하지 않음.
락을 사용하지 않는 대신, 애초에 스레드를 넘어서 데이터 수정을 할 수 없도록 막아버림.
결론
: Realm 데이터 수정은 main 스레드에서 이루어지게 합시다.
//데이터 수정은 main 스레드에서 DispatchQueue.main.async { try! self.realm.write { self.realm.delete(deleteData) } }
Realm accessed from incorrect thread (RLMException) 에러
틀린 내용이나 보완해야 할 내용이 있다면 댓글로 남겨주세요 :)
[참고자료]
'code' 카테고리의 다른 글
URLSession: 서버와 소통하는 주체, Json Decode (0) 2024.02.20 [SwiftUI] Firestore로 채팅 기능 구현하기 (0) 2023.10.26 지정생성자vs편의생성자, 클래스와 인스턴스의 메모리 구조 차이 (0) 2023.03.15 리스트에 자료 추가하기 (0) 2022.10.20 cvs 파일 python에서 쓰기 (0) 2022.10.20