Adakah amalan yang baik untuk meninggalkan pengembalian transaksi mongodb apabila ralat?

WBOY
Lepaskan: 2024-02-06 10:12:08
ke hadapan
431 orang telah melayarinya

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

Kandungan soalan

Saya menggunakan pemandu golanggo.mongodb.org/mongo-driver/mongo untuk mempelajari transaksi mongodb. Saya mengikuti ini jadi jawapan dan contoh ini di github.

Contoh kod diberikan oleh @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)
Salin selepas log masuk

Dalam kedua-dua contoh, mereka tidak akan berundur jika ralat berlaku. Saya tahu ini adalah contoh demo. Tetapi apabila saya melakukan perkara yang sama dalam kod, ia berfungsi dengan baik.

Adakah mungkin untuk mengetepikan rollback apabila ralat berlaku (adakah pemandu mengendalikannya)? Atau adakah saya kehilangan sesuatu?


Jawapan betul


mongo.withsession() tidak menganggap sebarang transaksi aktif, ia "hanya" membantu menjalankan panggilan balik di bawah sesi tertentu. Oleh itu, jika anda mahu ia dilaksanakan sebagai sebahagian daripada urus niaga yang dimulakan, anda harus mengendalikan komit dan menggugurkan sendiri. Ini membolehkan kawalan yang lebih halus.

Walau bagaimanapun, jika anda bercadang untuk menjalankan panggilan balik sebagai transaksi, gunakan session.withtransaction() kerana ia mengendalikan urus niaga dan kitaran hayatnya dengan cara yang telus: ia mencipta urus niaga dan melakukan atau membatalkannya berdasarkan ralat yang dikembalikan oleh panggilan balik. Sebagai ciri tambahan, ia juga boleh mengendalikan percubaan semula. Seperti yang ditunjukkan oleh dokumentasinya:

Jika panggilan balik gagal, pemandu akan memanggil aborttransaction.

Berikut ialah contoh mudah cara melaksanakan panggilan balik dengan betul dalam transaksi:

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
}
Salin selepas log masuk

Atas ialah kandungan terperinci Adakah amalan yang baik untuk meninggalkan pengembalian transaksi mongodb apabila ralat?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!