golang 有没办法在同个事务里面执行多个函数逻辑

2020-12-09 21:20:12 +08:00
 jmtung

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

func f1(){
// update user
}

func f2(){
// update order
}

func main(){
  tx,_ := db.Begin()
  f1()
  f2()
  tx.Commit()
}
3138 次点击
所在节点    Go 编程语言
11 条回复
labulaka521
2020-12-09 21:26:20 +08:00
放在 ctx 里
juzzle
2020-12-09 21:32:15 +08:00
@labulaka521 ctx 也需要传递给函数呀
dobelee
2020-12-09 21:49:08 +08:00
你都不用 ctx 的吗?
damngood
2020-12-09 22:03:01 +08:00
`func (ur *UserRepo) FetchUsersWithFilter(queryer sqlx.Queryer, filter *spms.UserFilter) ([]*spms.User, error) `

第一个参数既可以传事务也可以非事务, 我目前是这么做的.
godcc
2020-12-09 22:13:04 +08:00
好像只能把 tx 传进去
jmtung
2020-12-09 22:28:11 +08:00
感谢楼上大佬们的回答
@dobelee ctx 或者直接传 db 都是考虑过的,也是目前能想到的方式。但是这样的写法放在纯业务系统上感觉会复杂化了,所以寻求有没有更好的方式
CEBBCAT
2020-12-09 23:29:33 +08:00
我想到的是这样:
1. 定义一个结构体,将 tx 放入结构体后调用结构体的用户、订单更新函数
2. 参考 gin 的中间件的 c.Next () 的设计,但这样想必更复杂了

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

btw,我觉得可以讨论的一个问题是,什么样的编程思想才是 go 的
cheng6563
2020-12-10 01:18:10 +08:00
Java 那边的事务管理器也是 spring 给的,不用 spring 就要自己实现这个逻辑。
基本上就是第一次启动事务是真的启动并保持连接,如果调了其他函数再启动事务只是把递归计数器+1 。直到最外层的事务提交才是真的提交事务并释放连接。回滚同理。
当然还有其他事务传播策略,比如利用保存点什么的。
话说 orm 框架没处理这种事吗。
lewis89
2020-12-10 09:16:14 +08:00
@cheng6563 #8 golang 目前没有这些 类似切面处理逻辑的玩意 所以我不用 golang,spring 的声明式事务 基本上在切面已经处理的干干净净了没必要操心这种事情,有问题需要回滚 异常抛出去就行了
KaynW
2020-12-10 09:31:36 +08:00
gorm 有嵌套`事务
zarte
2020-12-10 09:56:44 +08:00
xorm 实现事务需要同个 session,实现不了你这个。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/733901

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX