Visão geral
Neste guia, você pode aprender como usar o MongoDB Go Driver para realizar transações. As transações permitem que você execute uma série de operações que não alteram nenhum dado até que a transação seja confirmada. Se alguma operação na transação retornar um erro, o driver cancelará a transação e descartará todas as alterações de dados antes que elas se tornem visíveis.
No MongoDB, as transações são executadas dentro de sessões lógicas. Uma sessão é um agrupamento de operações de leitura ou gravação relacionadas que você pretende executar sequencialmente. As sessões permitem consistência causal para um grupo de operações ou permitem que você execute operações em uma transação ACID. O MongoDB garante que os dados envolvidos em suas operações de transação permaneçam consistentes, mesmo que as operações encontrem erros inesperados.
Ao usar o driver Go, você pode criar uma nova sessão a partir de uma instância Client como tipo Session . Recomendamos que você reutilize seu cliente para várias sessões e transações, em vez de fazer a instância de um novo cliente a cada vez.
Aviso
Utilize uma Session apenas com o Client (ou Database ou Collection associada) que a criou. Utilizar uma Session com um Client diferente resulta em erros de operação.
Aviso
Implementações do Session não são seguras para uso concorrente por múltiplos goroutines.
Métodos de sessão
Depois de iniciar uma sessão usando o método StartSession() em seu cliente, você pode modificar o estado da sessão usando o conjunto de métodos fornecido pelo Session retornado. A tabela a seguir descreve esses métodos:
Método | Descrição |
|---|---|
| Inicia uma nova transação, configurada com as opções fornecidas, nesta sessão. Retorna um erro se já houver uma transação em andamento para a sessão. Para aprender mais sobre esse método, consulte a página startTransaction() no manual do servidor. |
| Termina a transação ativa para esta sessão. Retorna um erro se não houver uma transação ativa para a sessão ou se a transação tiver sido confirmada ou encerrada. Para saber mais sobre esse método, consulte a página abortTransaction() no manual do servidor. |
| Confirma a transação ativa para esta sessão. Retorna um erro se não houver nenhuma transação ativa para a sessão ou se a transação tiver sido encerrada. Para aprender mais sobre esse método, consulte a página commitTransaction() no manual do servidor.
|
| Inicia uma transação nesta sessão e executa a chamada de resposta |
| Encerra quaisquer transações existentes e fecha a sessão. |
Um Session também tem métodos para recuperar propriedades da sessão e modificar propriedades da sessão mutáveis. Consulte a documentação da API para saber mais sobre esses métodos.
Opções de Sessão e Transação
Você pode definir opções no nível da sessão e no nível da transação para personalizar como o driver realiza uma transação. As etapas a seguir descrevem como configurar opções para todas as transações executadas em um determinado Session:
Crie uma instância
TransactionOptions. Você pode especificar opções como preocupação de gravação, preocupação de leitura e preferência de leitura para todas as transações executadas em uma determinada sessão.Crie uma instância
SessionOptionschamando o métodoSetDefaultTransactionOptions(), passando a instânciaTransactionOptionscomo parâmetro.Você também pode especificar outras opções de sessão, como a consistência causal, na sua instância
SessionOptions.Passe a instância
SessionOptionspara o métodoclient.StartSession().
O código a seguir especifica as opções de sessão e transação e, em seguida, cria uma sessão com essas opções:
txnOpts := options.Transaction().SetReadConcern(readconcern.Majority()) sessOpts := options.Session().SetDefaultTransactionOptions(txnOpts) session, err := client.StartSession(sessOpts) if err != nil { return err }
Observação
Operações paralelas não suportadas
O driver Go não suporta a execução de operações paralelas dentro de uma única transação.
Se seu aplicativo estiver conectado ao MongoDB Server v8.0 ou posterior, você poderá executar operações de gravação em vários namespaces em uma única transação usando o recurso de gravação em massa do cliente. Para aprender mais, consulte a seção Client Bulk gravar do guia de operações em massa.
Exemplo
Os exemplos nesta seção usam o seguinte struct Book como o modelo de dados para os documentos inserir em uma coleção:
type Book struct { Title string `bson:"title"` Author string `bson:"author"` }
O exemplo a seguir mostra como você pode criar uma sessão, criar uma transação e confirmar uma operação de inserção de vários documentos por meio das seguintes etapas:
Crie uma sessão a partir do cliente usando o método
StartSession().Use o método
WithTransaction()para iniciar uma transação.Insere vários documentos. O método
WithTransaction()executa a inserção e confirma a transação. Se qualquer operação resultar em erros, oWithTransaction()lida com o cancelamento da transação.Feche a transação e a sessão usando o 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)
Exemplo de transação manual
Se você precisar de mais controle sobre suas transações, poderá criar, confirmar e encerrar transações manualmente. Este exemplo mostra como executar as seguintes ações:
Crie uma sessão a partir do cliente usando o método
StartSession().Use o método
StartTransaction()para iniciar uma transação.Insira vários documentos na transação.
Confirme a transação usando o método
CommitTransaction().Termine a sessão utilizando o 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) }
Informações adicionais
Para obter mais informações sobre operações de inserção, consulte a página de fundamentos de Inserir Documentos.
Para obter mais informações sobre a especificação de write concerns no driver Go, consulte write concern.
Para obter um exemplo adicional usando sessões e transações com o driver Go, consulte a postagem do blog do desenvolvedor sobre Transações ACID de vários documentos.
Documentação da API
Para saber mais sobre qualquer um dos tipos ou métodos discutidos neste guia, consulte a seguinte documentação da API: