I am using golang drivergo.mongodb.org/mongo-driver/mongo
Learning mongodb transactions. I'm following this so answer and this example on github.
Sample code given by @simagix:
if session, err = client.StartSession(); err != nil { t.Fatal(err) } if err = session.StartTransaction(); err != nil { t.Fatal(err) } if err = mongo.WithSession(ctx, session, func(sc mongo.SessionContext) error { if result, err = collection.UpdateOne(sc, bson.M{"_id": id}, update); err != nil { t.Fatal(err) } if result.MatchedCount != 1 || result.ModifiedCount != 1 { t.Fatal("replace failed, expected 1 but got", result.MatchedCount) } // more interrelated operations ... if err = session.CommitTransaction(sc); err != nil { t.Fatal(err) } return nil }); err != nil { t.Fatal(err) } session.EndSession(ctx)
In both examples, they will not rollback if an error occurs. I know this is a demo sample. But when I do the same in code, it works fine.
Is it possible to omit rollback when an error occurs (does the driver handle it)? Or am I missing something?
Here is a simple example of how to correctly execute callbacks within a transaction:
var docToInsert, idToUpdate, updateDoc any func doInTransactionExample(ctx context.Context, client *mongo.Client) error { sess, err := client.StartSession(options.Session().SetDefaultReadConcern(readconcern.Majority())) if err != nil { return fmt.Errorf("client.StartSession() error: %w", err) } defer sess.EndSession(ctx) result, err := sess.WithTransaction( ctx, func(sessCtx mongo.SessionContext) (any, error) { // sessCtx must be used as context.Context for all operations to be run in the transaction. var ctx context.Context = sessCtx // Shadow ctx on purpose! c := client.Database("foo").Collection("bar") // Insert example if _, err := c.InsertOne(ctx, docToInsert); err != nil { return nil, fmt.Errorf("InsertOne() failed: %w", err) } // Update example if ur, err := c.UpdateByID(ctx, idToUpdate, updateDoc); err != nil { return nil, fmt.Errorf("UpdateByID() failed: %w", err) } else { if ur.MatchedCount == 0 { return nil, fmt.Errorf("UpdateByID() failed: %w", mongo.ErrNoDocuments) } } return "arbitrary-result-to-return", nil }, options.Transaction().SetReadPreference(readpref.PrimaryPreferred()), ) if err != nil { return fmt.Errorf("sess.WithTransaction() error: %w", err) } _ = result // Not using result return nil }
The above is the detailed content of Is it a good practice to omit mongodb transaction rollback on error?. For more information, please follow other related articles on the PHP Chinese website!