Garantías de aislamiento
Lectura no confirmada
Dependiendo del nivel de consistencia de lectura, los clientes pueden ver los resultados de las operaciones de guardar antes de que se realicen. durable:
Independientemente del nivel de confirmación de escritura (write concern), otros clientes que utilizan
"local"o"available"el nivel de consistencia de lectura pueden ver el resultado de una operación de escritura antes de que la operación de escritura sea reconocida por el cliente que la solicita.Los clientes que utilizan
"local"o"available"como nivel de consistencia de lectura pueden leer datos que pueden ser posteriormente revertidos durante las conmutaciones por error del set de réplicas.
Para las operaciones en una transacción multi-documento, cuando una transacción se confirma, todos los cambios de datos realizados en la transacción se guardan y son visibles fuera de la transacción. Es decir, una transacción no realizará la confirmación de algunos de sus cambios mientras revierte otros.
Hasta que se produzca la confirmación de una transacción, los cambios de datos realizados en la transacción no son visibles fuera de la transacción.
Sin embargo, cuando una transacción se guarda en múltiples fragmentos, no todas las operaciones de lectura externas necesitan esperar a que el resultado de la transacción confirmada sea visible en todos los fragmentos. Por ejemplo, si se confirma una transacción y la escritura 1 es visible en el fragmento A, pero la escritura 2 aún no es visible en el fragmento B, una lectura externa con el nivel de consistencia de lectura "local" puede leer los resultados de la escritura 1 sin ver la escritura 2.
El nivel de aislamiento por defecto es lectura no confirmada y aplica a mongod instancias autónomas, sets de réplicas y clústeres.
Lectura no confirmada y atomicidad de documento único
Las operaciones de guardar son atómicas con respecto a un único documento; es decir, si una operación de guardar está actualizando varios campos en el documento, una operación de lectura nunca verá el documento con solo algunos de los campos actualizados. Sin embargo, aunque un cliente puede no ver un documento parcialmente actualizado, la lectura no confirmada significa que las operaciones de lectura concurrentes aún pueden ver el documento actualizado antes de que los cambios se hagan durables.
Con una instancia mongod autónoma, un conjunto de operaciones de lectura y escritura en un único documento es serializable. Con un set de réplicas, un conjunto de operaciones de lectura y escritura en un solo documento es serializable solo en ausencia de un rollback.
Lectura no confirmada y escritura de múltiples documentos
Cuando una sola operación de guardado (p. ej. db.collection.updateMany()) modifica múltiples documentos; la modificación de cada documento es atómica, pero la operación en su conjunto no es atómica.
Al realizar Operaciones de guardado multidocumento, ya sea a través de una sola Operación de guardado o de múltiples Operaciones de guardado, otras Operaciones pueden intercalarse.
Para situaciones que requieren atomicidad de las lecturas y escrituras en varios documentos (en una sola colección o en varias), MongoDB admite transacciones distribuidas, incluidas las transacciones en sets de réplica y clústeres fragmentados.
Para obtener más información, consulta transacciones.
Importante
En la mayoría de los casos, una transacción distribuida incurre en un costo de rendimiento mayor que las escrituras de documentos individuales, y la disponibilidad de transacciones distribuidas no debería ser un sustituto para un diseño de esquema efectivo. Para muchos casos, el modelo de datos desnormalizado (documento incrustado y matrices) seguirá siendo óptimo para tus datos y casos de uso. Es decir, en muchos casos, modelar tus datos de forma adecuada minimizará la necesidad de transacciones distribuidas.
Para consideraciones adicionales sobre el uso de transacciones (como el límite de tiempo de ejecución y el límite de tamaño del oplog), consulta también las consideraciones de producción.
Sin aislar las operaciones de escritura de múltiples documentos, MongoDB muestra el siguiente comportamiento:
Operaciones de lectura no puntuales en el tiempo. Supongamos que una operación de lectura comienza en el tiempo t 1 y comienza a leer documentos. Luego, una operación de escritura confirma una actualización de uno de los documentos en algún momento posterior t 2. El lector puede ver la versión actualizada del documento y, por lo tanto, no ve una snapshot de los datos en un punto en el tiempo.
Operaciones no serializables. Supongamos que una operación de lectura lee un documento d 1 en el momento t 1 y que una operación de escritura actualiza d 1 en algún momento posterior t 3. Esto introduce una dependencia de lectura-escritura tal que, si las operaciones se serializaran, la operación de lectura debe preceder a la operación de escritura. Pero también supongamos que la operación de escritura actualiza el documento d 2 en el momento t 2 y que la operación de lectura posteriormente lee d 2 en un momento posterior t 4. Esto introduce una dependencia de escritura-lectura que, en cambio, requeriría que la operación de lectura viniera después de la operación de escritura en un cronograma serializable. Existe un ciclo de dependencia que hace imposible la serializabilidad.
Las lecturas pueden omitir documentos coincidentes que se actualicen durante el transcurso de la operación de lectura.
Snapshot de cursor
Los cursores de MongoDB pueden devolver el mismo documento más de una vez en algunas situaciones. A medida que un cursor devuelve documentos, otras operaciones pueden intercalarse con la query. Si una de estas operaciones cambia el campo indexado en el índice utilizado por la query, entonces el cursor podría devolver el mismo documento más de una vez.
Las queries que utilizan índices únicos pueden, en algunos casos, devolver valores duplicados. Si un cursor que utiliza un índice único se entrelaza con un borrado y una inserción de documentos que comparten el mismo valor único, el cursor puede devolver el mismo valor único dos veces desde documentos diferentes.
Utiliza el aislamiento de lectura para mejorar la coherencia. Para obtener más información, consulta nivel de consistencia de lectura "snapshot".
Escrituras monotónicas
MongoDB proporciona garantías de escrituras monotónicas, por defecto, para instancias mongod autónomas y sets de réplicas.
Para escrituras monotónicas y clústeres fragmentados, consulta coherencia causal.
Las escrituras que no modifican ningún documento se conocen como escrituras de no operación noop. Escrituras de no-operación:
Ocurre si el filtro para escritura no coincide con ningún documento, o los documentos coincidentes no cambian después de aplicar la escritura.
No aumente el valor de optime.
Se devuelve
WriteResult.nModifiedigual a0, lo que indica que la operación de escritura no modificó ningún documento.
Para garantizar la monotonía con escrituras sin operación, utiliza garantías de coherencia causal. Para todas las demás escrituras, las siguientes secciones describen las garantías de monotonía.
Orden en tiempo real
Para operaciones de lectura y escritura en el primario, emitiendo "linearizable" nivel de consistencia de lectura para las lecturas y "majority" nivel de confirmación de escritura (write concern) para escrituras permite que varios hilos lean y escriban un solo documento como si una sola hebra ejecutara estas operaciones en tiempo real. El cronograma resultante para estas operaciones de lectura y escritura es linealizable.
Coherencia causal
Las operaciones que dependen lógicamente de una operación anterior tienen una relación causal. Por ejemplo, una guardar que borra todos los documentos que cumplen una condición especificada y una lectura posterior que verifica la operación de borrado tienen una relación causal.
Con las sesiones causalmente consistentes, MongoDB ejecuta operaciones causales en un orden que respeta sus relaciones causales. Los clientes observan resultados coherentes con esas relaciones.
Sesiones de cliente y garantías de coherencia causal
MongoDB habilita la coherencia causal a través de sesiones de clientes. Una sesión causalmente coherente garantiza que las operaciones de lectura con "majority" nivel de consistencia de lectura y las operaciones de escritura con "majority" nivel de confirmación de escritura (write concern) tengan una relación causal reflejada en su orden.
Las aplicaciones deben asegurarse de que solo un hilo a la vez ejecute estas operaciones en una sesión de cliente.
Para operaciones causalmente relacionadas:
Un cliente inicia una sesión de cliente.
Importante
Las sesiones de cliente solo garantizan la coherencia causal para:
Operaciones de lectura con
"majority"nivel de consistencia de lectura. La mayoría de los miembros del set de réplicas han reconocido los datos de retorno y son duraderos.Operaciones de escritura con un
"majority"nivel de confirmación de escritura (write concern). Estas operaciones solicitan un acuse de recibo de que el guardado se ha aplicado a la mayoría de los nodos con derecho a voto del set de réplicas.
Para aprender más sobre la coherencia causal y las preocupaciones de lectura y los niveles de confirmación de escritura, se puede consultar Coherencia causal y nivel de consistencia de lectura y nivel de confirmación de escritura.
A medida que el cliente emite operaciones de lectura con
"majority"nivel de consistencia de lectura y operaciones de escritura con"majority"nivel de confirmación de escritura (write concern), el cliente incluye información sobre la sesión con cada operación.Para cada operación de lectura con la
"majority"nivel de consistencia de lectura y la operación de escritura con la"majority"nivel de confirmación de escritura (write concern) asociada con la sesión, MongoDB devuelve la operation time y la hora del clúster, incluso si la operación tiene errores. La sesión del cliente rastrea la operation time y el tiempo del clúster.Nota
MongoDB no devuelve el optime ni el tiempo del clúster para las operaciones de escritura no reconocidas (
w: 0). Las escrituras no confirmadas no implican ninguna relación causal.MongoDB devuelve el operation time y el tiempo del clúster para las operaciones de lectura y las operaciones de escritura reconocidas en una sesión de cliente. Sólo las operaciones de lectura con
"majority"nivel de consistencia de lectura y las operaciones de escritura con"majority"nivel de confirmación de escritura (write concern) garantizan la coherencia causal. Para obtener más información, consulta coherencia causal y niveles de preocupación de lectura y escritura.La sesión de cliente asociada rastrea estos dos campos temporales.
Nota
Las operaciones pueden ser causalmente coherentes a través de diferentes sesiones. Los drivers de MongoDB y
mongoshproporcionan métodos para adelantar la operation time y la hora del clúster para una sesión de cliente. Un cliente puede avanzar el tiempo del clúster y el operation time de una sesión de cliente para que sean coherentes con las operaciones de otra sesión de cliente.
Garantías de coherencia causal
La siguiente tabla describe las garantías de consistencia causal para las sesiones causalmente consistentes que utilizan el nivel de consistencia de lectura "majority" para las operaciones de lectura y el nivel de confirmación de escritura (write concern) "majority" para las operaciones de escritura.
Garantías | Descripción |
|---|---|
Leer las escrituras | Las operaciones de lectura reflejan los resultados de las operaciones de escritura que las preceden. |
Lecturas monotónicas | Las operaciones de lectura no devuelven resultados que correspondan a un estado anterior de los datos que el de una operación de lectura precedente. Por ejemplo, si en una sesión:
entonces la lectura 2 no puede devolver resultados de escritura 1. |
Escrituras monotónicas | Las operaciones de escritura que deben preceder a otras operaciones de escritura se ejecutan antes que esas otras operaciones de escritura. Por ejemplo, si la escritura 1 debe preceder a la escritura 2 en una sesión, el estado de los datos en el momento de la escritura 2 debe reflejar el estado de los datos después de la escritura 1. Otras operaciones de escritura pueden intercalarse entre la escritura 1 y la escritura 2, pero la escritura 2 no puede ocurrir antes de la escritura 1. |
Las escrituras siguen a las lecturas | Las operaciones de escritura que deben realizarse después de las operaciones de lectura se ejecutan tras completar dichas operaciones de lectura. Es decir, el estado de los datos en el momento de la escritura debe incorporar el estado de los datos de las operaciones de lectura anteriores. |
preferencia de lectura
Estas garantías se mantienen en todos los nodos de la implementación de MongoDB. Por ejemplo, en una sesión causalmente consistente, si se emite una escritura con "majority" nivel de confirmación de escritura (write concern) seguida de una lectura desde un secundario con preferencia de lectura secondary y "majority" nivel de consistencia de lectura, la operación de lectura refleja el estado de la base de datos después de la operación de escritura.
Aislamiento
Las operaciones dentro de una sesión con coherencia causal no están aisladas de las operaciones fuera de la sesión. Si una operación de escritura concurrente se intercala entre las operaciones de escritura y lectura de la sesión, la operación de lectura de la sesión puede devolver resultados que reflejan una operación de escritura que ocurrió después de la operación de escritura de la sesión.
Controladores de MongoDB
Tip
Las aplicaciones deben asegurarse de que solo un hilo a la vez ejecute estas operaciones en una sesión de cliente.
Los clientes requieren controladores de MongoDB actualizados para MongoDB 3.6 o versiones posteriores:
Java 3.6+ Python 3.6+ C 1.9+ Go 1.8+ | C# 2.5+ Node 3.0+ Ruby 2.5+ Rust 2.1+ Swift 1.2+ | Perl 2.0+ PHPC 1.4+ Scala 2.2+ C++ 3.6.6+ |
Ejemplos
Importante
Las sesiones de coherencia causal solo garantizan la coherencia causal para las lecturas con nivel de consistencia de "majority" lectura y los escritos con nivel de "majority" confirmación de escritura (write concern).
Considera una colección items que mantiene datos actuales e históricos de varios elementos. Solo los datos históricos tienen una fecha de end que no es nula. Si el valor de sku de un elemento cambia, actualice el documento con el valor anterior de sku para agregar la fecha end y luego inserte un documento nuevo con el valor actual de sku. Utilice una sesión con consistencia causal para asegurarse de que la actualización ocurra antes de la inserción.
➤ Se puede usar el menú desplegable Seleccionar su lenguaje en la parte superior derecha para establecer el lenguaje de este ejemplo.
/* Use a causally-consistent session to run some operations. */ wc = mongoc_write_concern_new (); mongoc_write_concern_set_wmajority (wc, 1000); mongoc_collection_set_write_concern (coll, wc); rc = mongoc_read_concern_new (); mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_MAJORITY); mongoc_collection_set_read_concern (coll, rc); session_opts = mongoc_session_opts_new (); mongoc_session_opts_set_causal_consistency (session_opts, true); session1 = mongoc_client_start_session (client, session_opts, &error); if (!session1) { fprintf (stderr, "couldn't start session: %s\n", error.message); goto cleanup; } /* Run an update_one with our causally-consistent session. */ update_opts = bson_new (); res = mongoc_client_session_append (session1, update_opts, &error); if (!res) { fprintf (stderr, "couldn't add session to opts: %s\n", error.message); goto cleanup; } query = BCON_NEW ("sku", "111"); update = BCON_NEW ("$set", "{", "end", BCON_DATE_TIME (bson_get_monotonic_time ()), "}"); res = mongoc_collection_update_one (coll, query, update, update_opts, NULL, /* reply */ &error); if (!res) { fprintf (stderr, "update failed: %s\n", error.message); goto cleanup; } /* Run an insert with our causally-consistent session */ insert_opts = bson_new (); res = mongoc_client_session_append (session1, insert_opts, &error); if (!res) { fprintf (stderr, "couldn't add session to opts: %s\n", error.message); goto cleanup; } insert = BCON_NEW ("sku", "nuts-111", "name", "Pecans", "start", BCON_DATE_TIME (bson_get_monotonic_time ())); res = mongoc_collection_insert_one (coll, insert, insert_opts, NULL, &error); if (!res) { fprintf (stderr, "insert failed: %s\n", error.message); goto cleanup; }
using (var session1 = client.StartSession(new ClientSessionOptions { CausalConsistency = true })) { var currentDate = DateTime.UtcNow.Date; var items = client.GetDatabase( "test", new MongoDatabaseSettings { ReadConcern = ReadConcern.Majority, WriteConcern = new WriteConcern( WriteConcern.WMode.Majority, TimeSpan.FromMilliseconds(1000)) }) .GetCollection<BsonDocument>("items"); items.UpdateOne(session1, Builders<BsonDocument>.Filter.And( Builders<BsonDocument>.Filter.Eq("sku", "111"), Builders<BsonDocument>.Filter.Eq("end", BsonNull.Value)), Builders<BsonDocument>.Update.Set("end", currentDate)); items.InsertOne(session1, new BsonDocument { {"sku", "nuts-111"}, {"name", "Pecans"}, {"start", currentDate} }); }
// Example 1: Use a causally consistent session to ensure that the update occurs before the insert. ClientSession session1 = client.startSession(ClientSessionOptions.builder().causallyConsistent(true).build()); Date currentDate = new Date(); MongoCollection<Document> items = client.getDatabase("test") .withReadConcern(ReadConcern.MAJORITY) .withWriteConcern(WriteConcern.MAJORITY.withWTimeout(1000, TimeUnit.MILLISECONDS)) .getCollection("test"); items.updateOne(session1, eq("sku", "111"), set("end", currentDate)); Document document = new Document("sku", "nuts-111") .append("name", "Pecans") .append("start", currentDate); items.insertOne(session1, document);
async with await client.start_session(causal_consistency=True) as s1: current_date = datetime.datetime.today() items = client.get_database( "test", read_concern=ReadConcern("majority"), write_concern=WriteConcern("majority", wtimeout=1000), ).items await items.update_one( {"sku": "111", "end": None}, {"$set": {"end": current_date}}, session=s1 ) await items.insert_one( {"sku": "nuts-111", "name": "Pecans", "start": current_date}, session=s1 )
$items = $client->selectDatabase( 'test', [ 'readConcern' => new \MongoDB\Driver\ReadConcern(\MongoDB\Driver\ReadConcern::MAJORITY), 'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000), ], )->items; $s1 = $client->startSession( ['causalConsistency' => true], ); $currentDate = new \MongoDB\BSON\UTCDateTime(); $items->updateOne( ['sku' => '111', 'end' => ['$exists' => false]], ['$set' => ['end' => $currentDate]], ['session' => $s1], ); $items->insertOne( ['sku' => '111-nuts', 'name' => 'Pecans', 'start' => $currentDate], ['session' => $s1], );
with client.start_session(causal_consistency=True) as s1: current_date = datetime.datetime.today() items = client.get_database( "test", read_concern=ReadConcern("majority"), write_concern=WriteConcern("majority", wtimeout=1000), ).items items.update_one( {"sku": "111", "end": None}, {"$set": {"end": current_date}}, session=s1 ) items.insert_one( {"sku": "nuts-111", "name": "Pecans", "start": current_date}, session=s1 )
let s1 = client1.startSession(options: ClientSessionOptions(causalConsistency: true)) let currentDate = Date() var dbOptions = MongoDatabaseOptions( readConcern: .majority, writeConcern: try .majority(wtimeoutMS: 1000) ) let items = client1.db("test", options: dbOptions).collection("items") let result1 = items.updateOne( filter: ["sku": "111", "end": .null], update: ["$set": ["end": .datetime(currentDate)]], session: s1 ).flatMap { _ in items.insertOne(["sku": "nuts-111", "name": "Pecans", "start": .datetime(currentDate)], session: s1) }
let s1 = client1.startSession(options: ClientSessionOptions(causalConsistency: true)) let currentDate = Date() var dbOptions = MongoDatabaseOptions( readConcern: .majority, writeConcern: try .majority(wtimeoutMS: 1000) ) let items = client1.db("test", options: dbOptions).collection("items") try items.updateOne( filter: ["sku": "111", "end": .null], update: ["$set": ["end": .datetime(currentDate)]], session: s1 ) try items.insertOne(["sku": "nuts-111", "name": "Pecans", "start": .datetime(currentDate)], session: s1)
Para leer todos los valores actuales de sku de otro cliente, avance el tiempo del clúster y el operation time para que coincidan con los de la otra sesión. Esto asegura que el cliente sea causalmente coherente con la otra sesión y lea después de los dos guardados:
/* Make a new session, session2, and make it causally-consistent * with session1, so that session2 will read session1's writes. */ session2 = mongoc_client_start_session (client, session_opts, &error); if (!session2) { fprintf (stderr, "couldn't start session: %s\n", error.message); goto cleanup; } /* Set the cluster time for session2 to session1's cluster time */ cluster_time = mongoc_client_session_get_cluster_time (session1); mongoc_client_session_advance_cluster_time (session2, cluster_time); /* Set the operation time for session2 to session2's operation time */ mongoc_client_session_get_operation_time (session1, ×tamp, &increment); mongoc_client_session_advance_operation_time (session2, timestamp, increment); /* Run a find on session2, which should now find all writes done * inside of session1 */ find_opts = bson_new (); res = mongoc_client_session_append (session2, find_opts, &error); if (!res) { fprintf (stderr, "couldn't add session to opts: %s\n", error.message); goto cleanup; } find_query = BCON_NEW ("end", BCON_NULL); read_prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY); cursor = mongoc_collection_find_with_opts (coll, query, find_opts, read_prefs); while (mongoc_cursor_next (cursor, &result)) { json = bson_as_relaxed_extended_json (result, NULL); fprintf (stdout, "Document: %s\n", json); bson_free (json); } if (mongoc_cursor_error (cursor, &error)) { fprintf (stderr, "cursor failure: %s\n", error.message); goto cleanup; }
using (var session2 = client.StartSession(new ClientSessionOptions { CausalConsistency = true })) { session2.AdvanceClusterTime(session1.ClusterTime); session2.AdvanceOperationTime(session1.OperationTime); var items = client.GetDatabase( "test", new MongoDatabaseSettings { ReadPreference = ReadPreference.Secondary, ReadConcern = ReadConcern.Majority, WriteConcern = new WriteConcern(WriteConcern.WMode.Majority, TimeSpan.FromMilliseconds(1000)) }) .GetCollection<BsonDocument>("items"); var filter = Builders<BsonDocument>.Filter.Eq("end", BsonNull.Value); foreach (var item in items.Find(session2, filter).ToEnumerable()) { // process item } }
// Example 2: Advance the cluster time and the operation time to that of the other session to ensure that // this client is causally consistent with the other session and read after the two writes. ClientSession session2 = client.startSession(ClientSessionOptions.builder().causallyConsistent(true).build()); session2.advanceClusterTime(session1.getClusterTime()); session2.advanceOperationTime(session1.getOperationTime()); items = client.getDatabase("test") .withReadPreference(ReadPreference.secondary()) .withReadConcern(ReadConcern.MAJORITY) .withWriteConcern(WriteConcern.MAJORITY.withWTimeout(1000, TimeUnit.MILLISECONDS)) .getCollection("items"); for (Document item: items.find(session2, eq("end", BsonNull.VALUE))) { System.out.println(item); }
async with await client.start_session(causal_consistency=True) as s2: s2.advance_cluster_time(s1.cluster_time) s2.advance_operation_time(s1.operation_time) items = client.get_database( "test", read_preference=ReadPreference.SECONDARY, read_concern=ReadConcern("majority"), write_concern=WriteConcern("majority", wtimeout=1000), ).items async for item in items.find({"end": None}, session=s2): print(item)
$s2 = $client->startSession( ['causalConsistency' => true], ); $s2->advanceClusterTime($s1->getClusterTime()); $s2->advanceOperationTime($s1->getOperationTime()); $items = $client->selectDatabase( 'test', [ 'readPreference' => new \MongoDB\Driver\ReadPreference(\MongoDB\Driver\ReadPreference::SECONDARY), 'readConcern' => new \MongoDB\Driver\ReadConcern(\MongoDB\Driver\ReadConcern::MAJORITY), 'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000), ], )->items; $result = $items->find( ['end' => ['$exists' => false]], ['session' => $s2], ); foreach ($result as $item) { var_dump($item); }
with client.start_session(causal_consistency=True) as s2: s2.advance_cluster_time(s1.cluster_time) s2.advance_operation_time(s1.operation_time) items = client.get_database( "test", read_preference=ReadPreference.SECONDARY, read_concern=ReadConcern("majority"), write_concern=WriteConcern("majority", wtimeout=1000), ).items for item in items.find({"end": None}, session=s2): print(item)
let options = ClientSessionOptions(causalConsistency: true) let result2: EventLoopFuture<Void> = client2.withSession(options: options) { s2 in // The cluster and operation times are guaranteed to be non-nil since we already used s1 for operations above. s2.advanceClusterTime(to: s1.clusterTime!) s2.advanceOperationTime(to: s1.operationTime!) dbOptions.readPreference = .secondary let items2 = client2.db("test", options: dbOptions).collection("items") return items2.find(["end": .null], session: s2).flatMap { cursor in cursor.forEach { item in print(item) } } }
try client2.withSession(options: ClientSessionOptions(causalConsistency: true)) { s2 in // The cluster and operation times are guaranteed to be non-nil since we already used s1 for operations above. s2.advanceClusterTime(to: s1.clusterTime!) s2.advanceOperationTime(to: s1.operationTime!) dbOptions.readPreference = .secondary let items2 = client2.db("test", options: dbOptions).collection("items") for item in try items2.find(["end": .null], session: s2) { print(item) } }
Limitaciones
Las siguientes operaciones crean estructuras en memoria y no son causalmente consistentes:
Operación | notas |
|---|---|
| |
Devuelve un error si la operación está asociada con una sesión de cliente causalmente coherente. | |
Devuelve un error si la operación está asociada con una sesión de cliente causalmente coherente. | |
Devuelve un error si la operación está asociada con una sesión de cliente causalmente coherente. | |
Devuelve un error si la operación está asociada con una sesión de cliente causalmente coherente. | |