Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于多表事务 #235

Open
fesed opened this issue Mar 30, 2022 · 3 comments
Open

关于多表事务 #235

fesed opened this issue Mar 30, 2022 · 3 comments
Labels
question Further information is requested

Comments

@fesed
Copy link

fesed commented Mar 30, 2022

我看案例中的事务是单表的,请问多表事务是该怎么实现

@xsean2020
Copy link
Contributor

事务不是基于 sessCtx实现的嘛, 保证操作多表使用同一个 sessCtx 就行了

@LLiuHuan
Copy link

LLiuHuan commented Aug 1, 2022

事务不是基于 sessCtx实现的嘛, 保证操作多表使用同一个 sessCtx 就行了

大佬,有示例吗

@jiangz222 jiangz222 added the question Further information is requested label Oct 5, 2022
@orangesobeautiful
Copy link

@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")
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

5 participants