Transacciones de escritura
Realm utiliza un motor de almacenamiento altamente eficiente para persistir objetos. Se pueden crear, actualizar y, eventualmente, eliminar objetos en un reino. Dado que estas operaciones modifican el estado del reino, se denominan escrituras.
Realm gestiona las escrituras en términos de transacciones. Una transacción es una lista de operaciones de lectura y escritura que Realm trata como una sola operación indivisible. En otras palabras, una transacción es todo o nada: o todas las operaciones de la transacción se realizan correctamente o ninguna de ellas surte efecto.
Todas las escrituras deben realizarse en una transacción.
Un dominio solo permite una transacción abierta a la vez. El dominio bloquea otras escrituras en otros subprocesos hasta que la transacción abierta se complete. Por lo tanto, no hay condición de carrera al leer valores del dominio dentro de una transacción.
Cuando finalices tu transacción, Realm la confirma o la cancela:
Cuando Realm confirma una transacción, Realm guarda todos los cambios en el disco. Para los realms sincronizados, el SDK pone en cola el cambio para la sincronización con Atlas Device Sync.
Cuando Realm cancela una transacción de escritura o una operación en la transacción provoca un error, todos los cambios se descartan (o se "revierten").
Ejecutar una transacción
El SDK de Swift representa cada transacción como una función de devolución de llamada que contiene cero o más operaciones de lectura y escritura. Para ejecutar una transacción, defina una devolución de llamada de transacción y pásela al dominio. write Método. Con esta devolución de llamada, puede crear, leer, actualizar y eliminar datos en el reino. Si el código de la devolución de llamada genera una excepción al ejecutarse, Realm cancela la transacción. De lo contrario, Realm confirma la transacción inmediatamente después de la devolución de llamada.
Importante
Preocupaciones sobre la concurrencia
Dado que las transacciones se bloquean entre sí, es mejor evitar abrir transacciones tanto en el hilo de la interfaz de usuario como en un hilo en segundo plano. Si está utilizando Sincronización: evite abrir transacciones en el hilo de la interfaz de usuario, ya que Realm procesa las sincronizaciones en un hilo en segundo plano. Si una transacción en segundo plano bloquea la transacción de su hilo de la interfaz de usuario, su aplicación podría parecer inoperante.
Ejemplo
El siguiente código muestra cómo ejecutar una transacción con el método de escritura del dominio. Si el código de la devolución de llamada genera una excepción, Realm cancela la transacción. De lo contrario, la confirma.
// 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 ... }
Escrituras basadas en interfaz
Realm siempre envía notificaciones de forma asíncrona, por lo que nunca bloquean el hilo de la interfaz de usuario. Sin embargo, hay situaciones en las que la interfaz de usuario debe reflejar los cambios al instante. Si actualiza la interfaz de usuario directamente al mismo tiempo que escribe, la notificación podría duplicar la actualización. Esto podría provocar el bloqueo de la aplicación debido a una inconsistencia de estado entre la interfaz de usuario y el almacén de datos de respaldo. Para evitar esto, puede escribir sin enviar una notificación a un controlador específico. A este tipo de transacción lo llamamos escritura dirigida por la interfaz.
Ejemplo
Supongamos que decidimos gestionar manualmente la fuente de datos de una vista de tabla, ya que el diseño de nuestra aplicación requiere una respuesta instantánea a las actualizaciones de tabla basadas en la interfaz de usuario. En cuanto un usuario añade un elemento a la vista de tabla, lo insertamos en nuestra fuente de datos, lo que escribe en el dominio y, además, inicia inmediatamente la animación. Sin embargo, cuando el dominio envía la notificación de cambio para esta inserción un poco más tarde, indica que se ha añadido un objeto. ¡Pero ya actualizamos la vista de tabla! En lugar de escribir código complejo para gestionar este caso, podemos usar escrituras basadas en la interfaz para evitar que un controlador de notificación específico se active para esa escritura específica.
Las escrituras controladas por interfaz, también conocidas como escrituras silenciosas, son especialmente útiles al usar notificaciones de recopilación detalladas con un dominio sincronizado. Mientras que las escrituras controladas por interfaz se usan para las actualizaciones del usuario actual y actualizan la interfaz de usuario inmediatamente, el proceso de sincronización puede usar notificaciones estándar para actualizar la interfaz de usuario.