CRUD - Swift SDK
쓰기 트랜잭션(write transaction)
Realm 은 매우 효율적인 storage engine 을 사용하여 객체를 유지합니다. Realm에서 객체를 생성 하고, Realm에서 객체를 업데이트 하고, 최종적으로 Realm에서 객체를 삭제할 수 있습니다. 이러한 작업은 Realm의 상태를 수정하기 때문에 쓰기 작업이라고 합니다.
Realm은 트랜잭션 측면에서 쓰기를 처리합니다. 트랜잭션은 Realm이 분할할 수 없는 단일 작업으로 처리하는 읽기 및 쓰기 작업 목록입니다. 다시 말해, 트랜잭션은 전부 아니면 아무것도 아닙니다: 트랜잭션의 모든 작업이 성공하거나 트랜잭션의 작업 중 어느 것도 적용되지 않습니다.
모든 쓰기는 트랜잭션에서 이루어져야 합니다.
Realm은 한 번에 하나의 열린 트랜잭션만 허용합니다. Realm은 열린 트랜잭션이 완료될 때까지 다른 스레드에서 다른 쓰기를 차단합니다. 따라서 트랜잭션 내의 영역에서 값을 읽을 때 경쟁 조건이 없습니다.
트랜잭션이 완료되면 Realm은 트랜잭션을 커밋 하거나 취소 합니다.
Realm이 트랜잭션을 커밋 하면 Realm은 모든 변경 사항을 디스크에 기록합니다. 동기화된 영역의 경우 SDK는 Atlas Device Sync와의 동기화를 위해 변경 사항을 대기열에 추가합니다.
Realm이 쓰기 트랜잭션(write transaction)을 취소 하거나 트랜잭션 작업에서 오류가 발생하면 모든 변경 사항이 삭제(또는 "롤백")됩니다.
트랜잭션 실행
Swift SDK는 각 트랜잭션을 0개 이상의 읽기 및 쓰기 작업을 포함하는 콜백 함수로 나타냅니다. 트랜잭션을 실행하려면 트랜잭션 콜백을 정의하고 이를 영역의 write
메서드에 전달합니다. 이 콜백 내에서 영역에서 자유롭게 만들고, 읽고, 업데이트하고, 삭제할 수 있습니다. Realm에서 콜백의 코드가 실행할 때 예외가 발생하면 Realm은 트랜잭션을 취소합니다. 그렇지 않으면 Realm은 콜백 직후 트랜잭션을 커밋합니다.
중요
동시성 문제
트랜잭션은 서로를 차단 하므로 UI 스레드와 배경 스레드 모두에서 트랜잭션을 열지 않는 것이 가장 좋습니다. 동기화 를 사용하는 경우 Realm 은 배경 스레드에서 동기화를 처리하므로 UI 스레드에서 트랜잭션을 모두 열지 않도록 합니다. 배경 트랜잭션 이 UI 스레드의 트랜잭션 을 차단하는 경우 앱 이 응답하지 않는 것처럼 보일 수 있습니다.
예시
다음 코드는 Realm의 쓰기 (write) 메서드를 사용하여 트랜잭션 을 실행 하는 방법을 보여줍니다. 콜백 의 코드에서 예외가 발생하면 Realm 은 트랜잭션 을 취소합니다. 그렇지 않으면 Realm 이 트랜잭션 을 커밋합니다.
// Open the default realm. RLMRealm *realm = [RLMRealm defaultRealm]; // Open a thread-safe transaction. [realm transactionWithBlock:^() { // ... Make changes ... // Realm automatically cancels the transaction in case of exception. // Otherwise, Realm automatically commits the transaction at the // end of the code block. }];
// Open the default realm. let realm = try! Realm() // Prepare to handle exceptions. do { // Open a thread-safe transaction. try realm.write { // Make any writes within this code block. // Realm automatically cancels the transaction // if this code throws an exception. Otherwise, // Realm automatically commits the transaction // after the end of this code block. } } catch let error as NSError { // Failed to write to realm. // ... Handle error ... }
인터페이스 기반 쓰기
Realm 은 항상 알림 을 비동기적으로 전달하므로 UI 스레드를 차단 하지 않습니다. 그러나 UI 에 변경 사항을 즉시 반영해야 하는 상황이 있습니다. 쓰기 (write) 와 동시에 UI 를 직접 업데이트 하면 최종 알림이 해당 업데이트 를 double 수 있습니다. 이로 인해 UI 와 지원 데이터 저장 간의 일관성 없는 상태 로 인해 앱 이 충돌할 수 있습니다. 이를 방지하려면 특정 핸들러에 알림을 보내지 않고 쓰기 (write) 수 있습니다. 이러한 유형의 트랜잭션 을 인터페이스 기반 쓰기 (write)(write)라고 합니다.
예시
앱 디자인은 UI 기반 테이블 업데이트에 대한 즉각적인 응답을 요구하기 때문에 테이블 뷰의 데이터 소스를 수동으로 관리하기로 결정했다고 가정해 보겠습니다. 사용자가 테이블 뷰에 항목을 추가하면 데이터 소스에 해당 항목이 삽입되고 Realm은 Realm에 기록하지만 즉시 애니메이션이 시작됩니다. 그러나 잠시 후 Realm이 이 삽입에 대한 변경 알림을 전달하면 객체가 추가되었음을 나타냅니다. 그러나 이미 테이블 뷰를 업데이트했습니다! 이 경우를 처리하기 위해 복잡한 코드를 작성하는 대신 인터페이스 기반 쓰기를 사용하여 특정 쓰기에 대해 특정 알림 핸들러가 실행되는 것을 방지할 수 있습니다.
자동 쓰기라고도 하는 인터페이스 기반 쓰기는 동기화된 영역 영역 에서 세분화된 컬렉션 알림 을 사용할 때 특히 유용합니다. 현재 사용자의 업데이트에 인터페이스 기반 쓰기를 사용하고 UI 를 즉시 업데이트 하는 동안 동기화 프로세스 는 표준 알림 을 사용하여 UI 를 업데이트 할 수 있습니다.