-
Notifications
You must be signed in to change notification settings - Fork 13
Open
Labels
enhancementNew feature or requestNew feature or request
Description
使用场景 | Use Case Scenario
In the official MongoDB Go driver, transaction handling requires multiple manual steps, such as session management, transaction start/commit/abort, and context propagation.
This results in verbose boilerplate code and increases the risk of errors, especially in complex workflows.
To align with mongox's goal of improving developer ergonomics, we propose introducing high-level transaction wrapper APIs to simplify these operations.
可行方案 | Feasible Solutions
// Simplified transaction handling with automatic session management
func (c *Client) RunTransaction(
ctx context.Context,
fn func(ctx context.Context) (any, error),
txnOptions ...options.Lister[options.TransactionOptions],
) (any, error)
// Advanced transaction handling with manual session control
func (c *Client) WithManualTransaction(
ctx context.Context,
fn func(ctx context.Context, session *mongo.Session, txnOptions ...options.Lister[options.TransactionOptions]) error,
txnOptions ...options.Lister[options.TransactionOptions],
) errorUsage Examples:
- RunTransaction (Automatic session management):
result, err := client.RunTransaction(ctx, func(txCtx context.Context) (any, error) {
// Perform multiple operations within the transaction
_, err := userColl.Creator().InsertOne(txCtx, &User{Name: "Mingyong Chen", Age: 18})
if err != nil {
return nil, err
}
_, err := userColl.Updater().
Filter(query.Id("60e96214a21b1b0001c3d69e")).
Updates(update.Set("name", "Mingyong Chen")).
UpdateOne(txCtx)
if err != nil {
return nil, err
}
return "Transaction Successful", nil
})
if err != nil {
log.Fatalf("Transaction failed: %v", err)
}
fmt.Println("Transaction result:", result)- WithManualTransaction (Manual session control):
err := client.WithManualTransaction(ctx, func(txCtx context.Context, session *mongo.Session, txnOptions ...options.Lister[options.TransactionOptions]) error {
// Start a transaction manually
if err = session.StartTransaction(txnOptions); err != nil {
return err
}
// Perform operations
_, err := userColl.Creator().InsertOne(txCtx, &User{Name: "Mingyong Chen", Age: 18})
if err != nil {
return nil, err
}
_, err := userColl.Updater().
Filter(query.Id("60e96214a21b1b0001c3d69e")).
Updates(update.Set("name", "Mingyong Chen")).
UpdateOne(txCtx)
if err != nil {
return nil, err
}
if err = session.CommitTransaction(txCtx); err != nil {
return err
}
return nil
})
if err != nil {
log.Fatalf("Transaction failed: %v", err)
}
fmt.Println("Transaction completed successfully")These methods:
- Default to
writeConcern.Majority()(customizable viatxnOptions). - Automatically manage session lifecycle.
- Promote a clear, consistent pattern for transaction use.
This design was inspired by the official Go driver usage patterns and aims to streamline the most common transaction use cases.
其它 | Others
We’d love to gather feedback on:
- API naming: Are
RunTransactionandWithManualTransactionintuitive? Any preferred alternatives? - Design feedback: Does the proposed design align with your expectations for simplicity and flexibility?
- Additional features: Are there other transaction-related features you'd like to see in
mongox? For example:- Retry strategies for transient errors.
- Pre/post hooks for transaction lifecycle events.
- Metrics or logging integration for transaction monitoring.
Looking forward to community input and suggestions 🙌
If you’re interested in contributing, feel free to submit a PR!
codepzjcodepzj
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request