go-zero mongo 创建事务

mongo-driver拥有两种创建事务的方式,但两种方式对事务的开启关闭提交回滚操作有所不同

1.useSession(此处用go-zero举例)

func (m *customUserModel) UseSession(ctx context.Context) error {
    db := m.conn.Database()
    col := db.Collection("demo")
    _, err := col.InsertOne(ctx, bson.M{"_id": "111", "name": "testSession"})
    if err != nil {
        return err
    }
    //第一个事务:成功执行
    err = db.Client().UseSession(ctx, func(sessionContext mongo.SessionContext) error {
        err = sessionContext.StartTransaction()
        if err != nil {
            fmt.Println(err)
            return err
        }

        //在事务内写一条id为“222”的记录
        _, err = col.InsertOne(sessionContext, bson.M{"_id": "111", "name": "testSession"})
        if err != nil {
            fmt.Println(err)
            return err
        }

        //在事务内写一条id为“333”的记录
        _, err = col.InsertOne(sessionContext, bson.M{"_id": "333", "name": "ddd"})
        if err != nil {
            err := sessionContext.AbortTransaction(sessionContext)
            if err != nil {
                return err
            }
            return err
        } else {
            err := sessionContext.CommitTransaction(sessionContext)
            if err != nil {
                return err
            }
        }
        return nil
    })
    if err != nil {
        return err
    }
    err = db.Client().UseSession(ctx, func(sessionContext mongo.SessionContext) error {
        err := sessionContext.StartTransaction()
        if err != nil {
            fmt.Println(err)
            return err
        }

        //在事务内写一条id为“222”的记录
        _, err = col.InsertOne(sessionContext, bson.M{"_id": "444", "name": "ddd"})
        if err != nil {
            fmt.Println(err)
            return err
        }

        //写重复id
        _, err = col.InsertOne(sessionContext, bson.M{"_id": "111", "name": "ddd"})
        if err != nil {
            abortErr := sessionContext.AbortTransaction(sessionContext)
            if abortErr != nil {
                return abortErr
            }
            return err
        } else {
            err := sessionContext.CommitTransaction(sessionContext)
            if err != nil {
                return err
            }
        }
        return nil
    })
    if err != nil {
        return err
    }
    return nil
}

2.StartSession

func (m *customUserModel) WithSession(ctx context.Context) error {
    db := m.conn.Database()
    col := db.Collection("demo")
    msgCol := db.Collection("message")
    _, err := col.InsertOne(ctx, bson.M{"_id": "111", "user_name": "testSession"})
    if err != nil {
        return err
    }
    session, err := db.Client().StartSession()
    if err != nil {
        return err
    }
    defer func() {
        session.EndSession(ctx)
    }()
    _, err = session.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
        if err != nil {
            return nil, err
        }
        _, err = col.InsertOne(sessCtx, bson.M{"_id": "222", "user_name": "testSession2"})
        if err != nil {
            return nil, err
        }
        _, err = col.InsertOne(sessCtx, bson.M{"_id": "333", "user_name": "testSession2"})
        if err != nil {
            return nil, err
        }
        //_, err = col.InsertOne(sessCtx, bson.M{"_id": "111", "user_name": "testSession"})
        //if err != nil {
        //    return nil, err
        //}
        return true, nil
    })
    if err != nil {
        return err
    }
    return nil
}

可以看出1方式需要手动管理事务的提交回滚,2方式则需要管理事务的开启与关闭。具体可点进UseSession和WithTransaction观察下源码即可

如果执行代码后提示:Transaction numbers are only allowed on a replica set member or mongos

可参考:

MongoDB 运行事务时报“Transaction numbers are only allowed on a replica set member or mongos“错误

参考:

golang操作mongodb的驱动mongo-go-driver的事务支持和访问控制

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值