GORM 事务上下文传递
GORM 支持在多个方法间传递事务上下文,本文介绍其核心用法。
什么是事务上下文传递
事务上下文传递是指在多个方法或服务调用中,共享同一个事务实例,确保所有操作在同一事务内执行。
不使用事务上下文传递,每个方法独立开启事务,会导致操作分散在不同事务中,无法保证原子性。
上下文传递方式
使用 Session 方法
Go
// 创建带事务的 Session
tx := db.Session(&gorm.Session{})
func CreateUser(tx *gorm.DB, user *User) error {
return tx.Create(user).Error
}
func CreateOrder(tx *gorm.DB, order *Order) error {
return tx.Create(order).Error
}
// 调用方统一传递 tx
err := db.Transaction(func(tx *gorm.DB) error {
if err := CreateUser(tx, &user); err != nil {
return err
}
return CreateOrder(tx, &order)
})
使用 WithContext 方法
Go
// 将事务绑定到 context
ctx := context.Background()
tx := db.WithContext(ctx)
err := db.Transaction(func(tx *gorm.DB) error {
// WithContext 保持事务传播
ctx := tx.Statement.Context
return processWithCtx(ctx, tx)
})
多方法共用事务
Go
type OrderService struct {
DB *gorm.DB
}
func (s *OrderService) CreateOrderWithItems(order *Order, items []OrderItem) error {
return s.DB.Transaction(func(tx *gorm.DB) error {
// 传递 tx 给多个方法
if err := s.createOrder(tx, order); err != nil {
return err
}
if err := s.createItems(tx, items); err != nil {
return err
}
return s.updateStock(tx, items)
})
}
func (s *OrderService) createOrder(tx *gorm.DB, order *Order) error {
return tx.Create(order).Error
}
func (s *OrderService) createItems(tx *gorm.DB, items []OrderItem) error {
return tx.Create(&items).Error
}
所有方法接收同一个
tx参数,确保操作在同一事务内,任一方法失败都会导致整体回滚。
注意事项
- 方法签名中应明确声明
*gorm.DB参数,提示调用者传递事务对象 - 不要在方法内部调用
Begin()或Transaction(),应由调用方控制事务边界 WithContext用于传递 context,Session用于创建独立配置的事务实例- 跨服务调用可考虑使用 context 传递事务标识
要点总结
- 通过方法参数传递
*gorm.DB事务对象实现上下文共享 - 调用方负责事务边界,被调用方只执行操作
Session创建新配置实例,WithContext绑定 context- 避免在方法内部开启新事务,由调用方统一管理
文章存放路径:D:\git2\jwdev\articles\GORM\进阶\事务处理\事务上下文传递.md
📝 发现内容有误?点击此处直接编辑