Overview
En esta guía, aprenderá a usar el controlador de Scala para realizar transacciones. Las transacciones permiten realizar una serie de operaciones que modifican los datos solo si se confirma la transacción completa. Si alguna operación de la transacción no se realiza correctamente, el controlador la detiene y descarta todos los cambios en los datos antes de que sean visibles. Esta característica se denomina atomicidad.
En MongoDB, las transacciones se ejecutan dentro de sesiones lógicas. Una sesión es un agrupamiento de operaciones de lectura o guardado relacionadas que desea ejecutar en forma secuencial. Las sesiones permiten la coherencia causal para un grupo de operaciones y permiten ejecutar operaciones en una transacción compatible con ACID, que es una transacción que cumple una expectativa de atomicidad, consistencia, aislamiento y durabilidad. MongoDB garantiza que los datos involucrados en las operaciones de transacción se mantengan coherentes, incluso si las operaciones encuentran errores inesperados.
Al utilizar el controlador Scala, puede iniciar un ClientSession Al llamar al método startSession() en su cliente, podrá realizar transacciones dentro de la sesión.
Advertencia
Utilice un ClientSession solo en operaciones que se ejecuten en el MongoClient que lo creó. Usar un ClientSession con un MongoClient diferente da como resultado errores de operación.
Métodos
Después de llamar al método startSession() para iniciar una sesión, puedes usar métodos de la clase ClientSession para modificar el estado de la sesión. La siguiente tabla describe los métodos que puedes utilizar para gestionar una transacción:
Método | Descripción |
|---|---|
| Starts a new transaction on this session. You cannot start a
transaction if there's already an active transaction running in
the session. You can set transaction options by passing a TransactionOptions
instance as a parameter. |
| Commits the active transaction for this session. This method returns an
error if there is no active transaction for the session, the
transaction was previously ended, or if there is a write conflict. |
| Ends the active transaction for this session. This method returns an
error if there is no active transaction for the session or if the
transaction was committed or ended. |
Tip
Tiempo de espera de transacción
Puede establecer un límite de tiempo para completar las operaciones de sus transacciones. Para obtener más información, consulte Transactions sección de la guía sobre Límite de Tiempo de Ejecución del Servidor.
Ejemplo de transacción
Este ejemplo define un método runTransaction() que modifica datos en las colecciones de la base de datos sample_mflix. El código realiza las siguientes acciones:
Crea
MongoCollectioninstancias para acceder a las coleccionesmoviesyusersEspecifica la preocupación de lectura y el nivel de confirmación de escritura (write concern) para la transacción
Inicia la transacción
Inserta un documento en la colección
moviese imprime los resultadosActualiza un documento en la colección
userse imprime los resultados
def runTransaction( database: MongoDatabase, observable: SingleObservable[ClientSession] ): SingleObservable[ClientSession] = { observable.map(clientSession => { val moviesCollection = database.getCollection("movies") val usersCollection = database.getCollection("users") val transactionOptions = TransactionOptions .builder() .readConcern(ReadConcern.SNAPSHOT) .writeConcern(WriteConcern.MAJORITY) .build() // Starts the transaction with specified options clientSession.startTransaction(transactionOptions) // Inserts a document into the "movies" collection val insertObservable = moviesCollection.insertOne( clientSession, Document("name" -> "The Menu", "runtime" -> 107) ) val insertResult = Await.result(insertObservable.toFuture(), Duration(10, TimeUnit.SECONDS)) println(s"Insert completed: $insertResult") // Updates a document in the "users" collection val updateObservable = usersCollection.updateOne( clientSession, equal("name", "Amy Phillips"), set("name", "Amy Ryan") ) val updateResult = Await.result(updateObservable.toFuture(), Duration(10, TimeUnit.SECONDS)) println(s"Update completed: $updateResult") clientSession }) }
Nota
Dentro de una transacción, las operaciones deben ejecutarse en secuencia. El código anterior espera el resultado de cada operación de guardar para garantizar que las operaciones no se ejecuten simultáneamente.
A continuación, ejecuta el siguiente código para realizar la transacción. Este código completa las siguientes acciones:
Crea una sesión desde el cliente usando el método
startSession()Llama al método
runTransaction()definido en el ejemplo anterior, pasando la base de datos y la sesión como parámetrosConfirma la transacción llamando al método
commitTransaction()y espera a que se completen las operaciones.
val client = MongoClient("<connection string>") val database = client.getDatabase("sample_mflix") val session = client.startSession(); val transactionObservable: SingleObservable[ClientSession] = runTransaction(database, session) val commitTransactionObservable: SingleObservable[Unit] = transactionObservable.flatMap(clientSession => clientSession.commitTransaction()) Await.result(commitTransactionObservable.toFuture(), Duration(10, TimeUnit.SECONDS))
Insert completed: AcknowledgedInsertOneResult{insertedId=BsonObjectId{value=...}} Update completed: AcknowledgedUpdateResult{matchedCount=1, modifiedCount=1, upsertedId=null}
Nota
Operaciones paralelas no admitidas
El driver de Scala no admite la ejecución de operaciones en paralelo dentro de una sola transacción.
Si utilizas MongoDB Server v8.0 o posterior, puedes realizar operaciones de escritura en varios namespaces dentro de una sola transacción utilizando la funcionalidad de escritura masiva del cliente. Para obtener más información sobre esta funcionalidad, consulta la guía Operaciones de escritura masiva.
Información Adicional
Para obtener más información sobre los conceptos mencionados en esta guía, consulte las siguientes páginas del manual de MongoDB Server:
Para obtener más información sobre el cumplimiento de ACID, consulte el artículo Una guía de propiedades ACID en sistemas de administración de bases de datos en el sitio web de MongoDB.
Para obtener más información sobre las operaciones de inserción, consulte la Guía de Inserción de Documentos.
Documentación de la API
Para obtener más información sobre los métodos y tipos mencionados en esta guía, vea la siguiente documentación de la API: