Open fesed opened 2 years ago
事务不是基于 sessCtx实现的嘛, 保证操作多表使用同一个 sessCtx 就行了
事务不是基于 sessCtx实现的嘛, 保证操作多表使用同一个 sessCtx 就行了
大佬,有示例吗
@fesed 使用 qmgo.Client 來進行操作即可 以下範例是 TestSession_AbortTransaction 函數的修改版
package main
import (
"context"
"fmt"
"log"
"github.com/qiniu/qmgo"
"go.mongodb.org/mongo-driver/bson"
)
const (
// abortTransaction 是否要中斷 Transaction
abortTransaction = false
)
func main() {
bgCtx := context.Background()
cfg := qmgo.Config{
// 記得修改成自己的資料庫設定
Uri: "mongodb://user:password@localhost:27017",
}
// 用 *qmgo.Client 才能達成多 Collection 操作需求
qClient, err := qmgo.NewClient(bgCtx, &cfg)
if err != nil {
log.Fatalf("qmgo.Open failed, err=%s", err)
}
db := qClient.Database("testdb")
col1 := db.Collection("coll1")
col2 := db.Collection("coll2")
sess, _ := qClient.Session()
defer sess.EndSession(bgCtx)
defer func() {
_ = col1.DropCollection(bgCtx)
_ = col2.DropCollection(bgCtx)
}()
// 定義 Transaction 中要做的事項
// 注意 context 要使用的是傳進來的參數 sessCtx
callback := func(sessCtx context.Context) (interface{}, error) {
if _, err := col1.InsertOne(sessCtx, bson.M{"abc": int32(1)}); err != nil {
return nil, err
}
if _, err := col2.InsertOne(sessCtx, bson.M{"xyz": int32(999)}); err != nil {
return nil, err
}
if abortTransaction {
_ = sess.AbortTransaction(sessCtx)
}
return nil, nil
}
// 執行 Transaction
_, err = sess.StartTransaction(bgCtx, callback)
if err != nil {
log.Fatalf("StartTransaction failed, err=%s", err)
}
// 檢測資料有沒有寫入
r := bson.M{}
err = col1.Find(bgCtx, bson.M{"abc": 1}).One(&r)
if err != nil {
fmt.Println("abc found failed", err)
} else {
fmt.Println("find abc")
}
err = col2.Find(bgCtx, bson.M{"xyz": 999}).One(&r)
if err != nil {
fmt.Println("xyz found failed", err)
} else {
fmt.Println("find xyz")
}
}
我看案例中的事务是单表的,请问多表事务是该怎么实现