Golang Go语言中有没有办法在同个事务里面执行多个函数逻辑

发布于 1周前 作者 itying888 来自 Go语言

Golang Go语言中有没有办法在同个事务里面执行多个函数逻辑

不用函数传参的情况下,实现类似以下的功能,在 php 里面能用单请求下的数据库单例实现,go 有没有类似的方案。搜了一下在 java 那边应该叫事务传播或者需要一个事务管理器。

func f1(){
// update user
}

func f2(){
// update order
}

func main(){
  tx,_ := db.Begin()
  f1()
  f2()
  tx.Commit()
}

更多关于Golang Go语言中有没有办法在同个事务里面执行多个函数逻辑的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

12 回复

放在 ctx 里

更多关于Golang Go语言中有没有办法在同个事务里面执行多个函数逻辑的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


ctx 也需要传递给函数呀

你都不用 ctx 的吗?

func (ur *UserRepo) FetchUsersWithFilter(queryer sqlx.Queryer, filter *spms.UserFilter) ([]*spms.User, error)

第一个参数既可以传事务也可以非事务, 我目前是这么做的.

好像只能把 tx 传进去

感谢楼上大佬们的回答
ctx 或者直接传 db 都是考虑过的,也是目前能想到的方式。但是这样的写法放在纯业务系统上感觉会复杂化了,所以寻求有没有更好的方式

我想到的是这样:
1. 定义一个结构体,将 tx 放入结构体后调用结构体的用户、订单更新函数
2. 参考 gin 的中间件的 c.Next () 的设计,但这样想必更复杂了

可能是我没读懂,为什么一定要不传入相关参数呢?这样是不是合理呢?

btw,我觉得可以讨论的一个问题是,什么样的编程思想才是 go 的

Java 那边的事务管理器也是 spring 给的,不用 spring 就要自己实现这个逻辑。
基本上就是第一次启动事务是真的启动并保持连接,如果调了其他函数再启动事务只是把递归计数器+1 。直到最外层的事务提交才是真的提交事务并释放连接。回滚同理。
当然还有其他事务传播策略,比如利用保存点什么的。
话说 orm 框架没处理这种事吗。

#8 golang 目前没有这些 类似切面处理逻辑的玩意 所以我不用 golang,spring 的声明式事务 基本上在切面已经处理的干干净净了没必要操心这种事情,有问题需要回滚 异常抛出去就行了

gorm 有嵌套`事务

xorm 实现事务需要同个 session,实现不了你这个。

在Go语言中,直接提供事务管理支持的是数据库驱动或ORM(对象关系映射)库,而不是Go语言本身。Go语言的标准库并没有内置的事务处理机制,但你可以通过数据库驱动或ORM库来实现事务管理。

要在同一个事务中执行多个函数逻辑,你需要确保这些函数能够接收和操作同一个数据库事务对象。这通常涉及以下步骤:

  1. 开启事务:在数据库连接上开始一个新的事务。
  2. 传递事务对象:将事务对象作为参数传递给需要在这个事务中执行的函数。
  3. 执行函数逻辑:在每个函数中,使用传递进来的事务对象执行数据库操作。
  4. 提交或回滚事务:根据所有函数执行的结果,决定是提交事务还是回滚事务。

以下是一个简单的示例,使用Go语言的database/sql包和MySQL数据库:

func main() {
    db, err := sql.Open("mysql", "dsn")
    if err != nil {
        log.Fatal(err)
    }
    tx, err := db.Begin()
    if err != nil {
        log.Fatal(err)
    }
    defer func() {
        if err != nil {
            tx.Rollback()
        } else {
            tx.Commit()
        }
    }()
    err = func1(tx)
    if err != nil {
        return
    }
    err = func2(tx)
    if err != nil {
        return
    }
}

在这个示例中,func1func2都接收一个*sql.Tx对象作为参数,并在该事务中执行数据库操作。

回到顶部