Overview
En esta guía, puede aprender a utilizar el controlador MongoDB Go para realizar transacciones. Transacciones le permiten ejecutar una serie de operaciones que no cambian ningún dato hasta que la transacción es confirmada. Si alguna operación en la transacción devuelve un error, el driver cancela la transacción y descarta todos los cambios de datos antes de que sean visibles.
En MongoDB, las transacciones se ejecutan dentro de sesiones lógicas. Una sesión es un agrupamiento de operaciones de lectura o escritura relacionadas que usted planea ejecutar secuencialmente. Las sesiones habilitan la coherencia causal para un conjunto de operaciones o te permiten ejecutar operaciones en una ACID transaction. MongoDB garantiza que los datos involucrados en sus operaciones de transacción permanezcan coherentes, incluso si las operaciones encuentran errores inesperados.
Al utilizar el driver de Go, puede crear una nueva sesión desde un
Client instancia como un tipo Session. Recomendamos reutilizar su cliente para múltiples sesiones y transacciones en lugar de crear una nueva instancia de cliente cada vez.
Advertencia
Utiliza un Session solo con el Client (o el Database o Collection asociados) que lo creaste. El uso de un Session con un Client diferente resulta en errores de operación.
Advertencia
Las implementaciones de Session no son seguras para el uso concurrente por múltiples goroutines.
Métodos de sesión
Después de iniciar una sesión con el método StartSession() en su cliente, puede modificar el estado de la sesión mediante el conjunto de métodos proporcionado por el Session devuelto. La siguiente tabla describe estos métodos:
Método | Descripción |
|---|---|
| Starts a new transaction, configured with the given options, on
this session. Returns an error if there is already
a transaction in progress for the session. To learn more about
this method, see the startTransaction() page in the Server manual. Parameter: TransactionOptionsReturn Type: error |
| Ends the active transaction for this session. Returns an
error if there is no active transaction for the session or the
transaction has been committed or ended. To learn more about
this method, see the abortTransaction() page in the Server manual. Parameter: ContextReturn Type: error |
| Commits the active transaction for this session. Returns an
error if there is no active transaction for the session or if the
transaction was ended. To learn more about
this method, see the commitTransaction() page in the Server manual. The CommitTransaction() method is an idempotent function, which
means that you can attempt to commit a transaction multiple times without changing data after the first successful commit.
A transaction can succeed but return an error with the
UnknownTransactionCommitResult label. If you rerun the
CommitTransaction() method after receiving this error,
your data is not changed by the repeat attempts.Parameter: ContextReturn Type: error |
| Starts a transaction on this session and runs the fn
callback.Parameters: Context, fn func(ctx SessionContext), TransactionOptionsReturn Type: any, error |
| Ends any existing transactions and closes the session. Parameter: ContextReturn Type: none |
Un Session también tiene métodos para recuperar propiedades de sesión y modificar propiedades de sesión mutables. Consulta la documentación de la API para aprender más sobre estos métodos.
Opciones de sesión y transacción
Puede establecer opciones a nivel de sesión y a nivel de transacción para personalizar el rendimiento de la transacción por parte del controlador. Los siguientes pasos describen cómo establecer opciones para todas las transacciones que se ejecuten dentro de un(a) determinado(a) Session:
Cree una instancia de
TransactionOptions. Puedes especificar opciones como nivel de confirmación de escritura (write concern), nivel de consistencia de lectura y preferencia de lectura para todas las transacciones ejecutadas en una sesión dada.Crea una instancia
SessionOptionsllamando al métodoSetDefaultTransactionOptions()y pasando la instanciaTransactionOptionscomo parámetro.También puedes especificar otras opciones de sesión, como la consistencia causal en tu instancia
SessionOptions.Pase la instancia
SessionOptionsal métodoclient.StartSession().
El siguiente código especifica opciones de sesión y transacción, luego crea una sesión con estas opciones:
txnOpts := options.Transaction().SetReadConcern(readconcern.Majority()) sessOpts := options.Session().SetDefaultTransactionOptions(txnOpts) session, err := client.StartSession(sessOpts) if err != nil { return err }
Nota
Operaciones paralelas no admitidas
El controlador Go no admite la ejecución de operaciones en paralelo dentro de una sola transacción.
Si su aplicación está conectada a MongoDB Server v8.0 o posterior, puede realizar operaciones de escritura en varios espacios de nombres dentro de una sola transacción mediante la función de escritura masiva del cliente. Para obtener más información, consulte Sección Escritura Masiva de Cliente en la guía de Operaciones Masivas.
Ejemplo
Los ejemplos de esta sección usan la siguiente estructura de Book como el modelo de datos para los documentos que se insertarían en una colección:
type Book struct { Title string `bson:"title"` Author string `bson:"author"` }
El siguiente ejemplo muestra cómo puedes crear una sesión, crear una transacción y confirmar una operación de inserción de varios documentos mediante los siguientes pasos:
Cree una sesión desde el cliente utilizando el método
StartSession().Utilice el método
WithTransaction()para iniciar una transacción.Inserte varios documentos. El método
WithTransaction()ejecuta la inserción y confirma la transacción. Si alguna operación resulta en errores,WithTransaction()gestiona la cancelación de la transacción.Cierra la transacción y la sesión utilizando el método
EndSession().
wc := writeconcern.Majority() txnOptions := options.Transaction().SetWriteConcern(wc) // Starts a session on the client session, err := client.StartSession() if err != nil { panic(err) } // Defers ending the session after the transaction is committed or ended defer session.EndSession(context.TODO()) // Inserts multiple documents into a collection within a transaction, // then commits or ends the transaction result, err := session.WithTransaction(context.TODO(), func(ctx context.Context) (any, error) { result, err := coll.InsertMany(ctx, []any{ Book{Title: "The Bluest Eye", Author: "Toni Morrison"}, Book{Title: "Sula", Author: "Toni Morrison"}, Book{Title: "Song of Solomon", Author: "Toni Morrison"}, }) return result, err }, txnOptions)
Ejemplo de Transacción Manual
Si requiere más control sobre sus transacciones, puede crearlas, comprometerlas y finalizarlas manualmente. Este ejemplo demuestra cómo realizar las siguientes acciones:
Cree una sesión desde el cliente utilizando el método
StartSession().Utilice el método
StartTransaction()para iniciar una transacción.Inserte varios documentos dentro de la transacción.
Confirme la transacción utilizando el método
CommitTransaction().Termina la sesión utilizando el método
EndSession().
wc := writeconcern.Majority() txnOptions := options.Transaction().SetWriteConcern(wc) // Starts a session on the client session, err := client.StartSession() if err != nil { panic(err) } // Defers ending the session after the transaction is committed or ended defer session.EndSession(context.TODO()) err = mongo.WithSession(context.TODO(), session, func(ctx context.Context) error { if err = session.StartTransaction(txnOptions); err != nil { return err } docs := []any{ Book{Title: "The Year of Magical Thinking", Author: "Joan Didion"}, Book{Title: "Play It As It Lays", Author: "Joan Didion"}, Book{Title: "The White Album", Author: "Joan Didion"}, } result, err := coll.InsertMany(ctx, docs) if err != nil { return err } if err = session.CommitTransaction(ctx); err != nil { return err } fmt.Println(result.InsertedIDs) return nil }) if err != nil { if err := session.AbortTransaction(context.TODO()); err != nil { panic(err) } panic(err) }
Información Adicional
Para obtener más información sobre las operaciones de inserción, consulte la página Fundamentos de Insertar documentos.
Para obtener más información sobre cómo especificar write concerns en el driver de Go, consulta Nivel de confirmación de escritura (write concern).
Para un ejemplo adicional utilizando sesiones y transacciones con el controlador Go, consulta la entrada de blog para desarrollador sobre Transacciones ACID Multidocumento.
Documentación de la API
Para obtener más información sobre cualquiera de los tipos o métodos analizados en esta guía, consulte la siguiente documentación de API: