Go语言数据库编程:数据迁移与事务控制

发布于:2025-06-30 ⋅ 阅读:(11) ⋅ 点赞:(0)

以下是《Go语言实战指南》中关于 数据库编程:数据迁移与事务控制 的核心内容,适用于使用 GORM 进行数据库表结构管理与事务性操作。


一、数据迁移(AutoMigrate)

GORM 提供 AutoMigrate() 方法可根据结构体自动创建或更新数据库表结构,适合开发阶段使用。

1. 自动创建表结构
db.AutoMigrate(&User{})
  • • 会创建表、缺失字段、索引。
  • • 不会删除字段、修改字段类型,所以是“非破坏性迁移”。
  • • 多个模型可一并迁移:
db.AutoMigrate(&User{}, &Product{}, &Order{})
2. 常见字段标签
GORM 标签 功能说明
primaryKey 主键
uniqueIndex 唯一索引
size:255 设置字段长度
default:'abc' 设置默认值
not null 不允许为 NULL
3. 嵌套字段自动迁移
type Address struct {
    City string
    Zip  string
}

type User struct {
    gorm.Model
    Name    string
    Address Address `gorm:"embedded"`
}

二、事务控制(Transaction)

在实际开发中,涉及多个数据库操作时应使用事务保证一致性。

1. 使用 db.Transaction() 执行事务
err := db.Transaction(func(tx *gorm.DB) error {
    if err := tx.Create(&User{Name: "Tom"}).Error; err != nil {
        return err
    }

    if err := tx.Create(&Order{UserID: 1, Amount: 100}).Error; err != nil {
        return err
    }

    return nil // 提交事务
})
if err != nil {
    log.Println("事务失败:", err)
}
  • • 返回 nil:自动提交。
  • • 返回 error:自动回滚。
2. 手动控制事务(更细粒度)
tx := db.Begin()
defer func() {
    if r := recover(); r != nil {
        tx.Rollback()
    }
}()

if err := tx.Create(&User{Name: "Alice"}).Error; err != nil {
    tx.Rollback()
    return
}

if err := tx.Create(&Order{UserID: 1}).Error; err != nil {
    tx.Rollback()
    return
}

tx.Commit()

✅ 遇 panic 时可通过 defer + recover 回滚事务,防止程序异常提交。


三、事务的隔离级别(可选配置)

使用 Set 方法可设置隔离级别:

db.Session(&gorm.Session{
    Isolation: "REPEATABLE READ",
}).Transaction(func(tx *gorm.DB) error {
    // 操作...
    return nil
})

常见的隔离级别有:

  • • READ UNCOMMITTED
  • • READ COMMITTED
  • • REPEATABLE READ(MySQL 默认)
  • • SERIALIZABLE

四、在 Gin 项目中统一管理事务(实践建议)

如果你使用的是 Gin 框架,可以在中间件中开启事务,将事务对象绑定到 context.Context 中,在业务层统一使用:

// 开启事务中间件
func TransactionMiddleware(db *gorm.DB) gin.HandlerFunc {
    return func(c *gin.Context) {
        tx := db.Begin()
        c.Set("tx", tx)

        c.Next()

        if len(c.Errors) > 0 {
            tx.Rollback()
        } else {
            tx.Commit()
        }
    }
}

业务中获取并使用:

tx := c.MustGet("tx").(*gorm.DB)
tx.Create(&User{})

五、小结

功能点 方法 / 实践
自动迁移 db.AutoMigrate(&Model{})
表结构控制 通过 GORM 标签控制字段属性
简单事务 db.Transaction(func(tx *gorm.DB) error)
手动事务 Begin / Commit / Rollback
项目实践 中间件中开启事务,绑定到上下文使用


网站公告

今日签到

点亮在社区的每一天
去签到