Is it a good practice to omit mongodb transaction rollback on error?

WBOY
Release: 2024-02-06 10:12:08
forward
454 people have browsed it

在发生错误时省略 mongodb 事务回滚是一个好习惯吗

Question content

I am using golang drivergo.mongodb.org/mongo-driver/mongoLearning 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)
Copy after login

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?


Correct Answer


##mongo.withsession() It does not assume any active transaction, it "only" helps To run the callback for a given session. Therefore, if you want it to be executed as part of the initiated transaction, you should handle the commit and abort yourself. This allows for finer control.

However, if you intend to run the callback as a transaction, use

session.withtransaction() because it handles transactions and their lifecycle in a transparent way: it creates the transaction and Submit or abort it based on the error returned by the callback. As an added feature, it can also handle retries. As its documentation also points out:

If the callback fails, the driver will call aborttransaction.

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
}
Copy after login

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!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!