Skip to content

12.3 数据访问铁律 ​

必须遵守

数据访问的四条红线:禁止裸用 *gorm.DB、一切删除走软删除、Raw 受限使用、事务统一 WithTrans。违反任何一条都会破坏租户隔离或审计完整性。

铁律一:禁止裸用 *gorm.DB ​

go
// 正确
repository.NewUserRepo().Ctx(ctx).Where(...).Find(...)

// 禁止
db.DB.Where(...)           // 全局句柄直用
gorm.Open(...)             // 业务层自建连接

Ctx(ctx) 是唯一常规入口——软删过滤与租户隔离在此注入,绕过即裸奔。

铁律二:一切删除走软删除 ​

go
repo.SoftDelete(ctx, "id", id)      // UPDATE del_flag=1
repo.SoftDeleteByID(ctx, id)

物理 DELETE 被全局钩子拦截。确需物理清理(定时任务清超期日志):

go
ctx = hooks.WithPhysicalDelete(ctx)  // 显式放行,作用域仅此链路

铁律三:Raw 仅限明确场景 ​

Raw() 不注入任何 Scope(已删数据可见、跨租户可见),仅限:

  • 导入(批量落库)
  • 字典管理(平台级维护)
  • 登录校验(公开路由无租户身份)

使用处必须注释说明场景正当性,且条件完整性由使用者自行保证。

铁律四:事务统一 WithTrans ​

go
db.WithTrans(ctx, func(ctx context.Context) error {
    // 回调内一律用入参 ctx(携带事务连接)
    // 返回非 nil 错误整体回滚
})

跨模块写操作必须同事务;钩子在事务内同样生效(审计盖章一致)。

常见违反与后果 ​

违反后果
裸 DB 查询查到已删数据、跨租户数据泄露
业务代码物理删除审计链断裂,无法追责
Raw 当常规用同裸 DB,且逐渐扩散
事务用外层 ctx事务内查询落回连接池,回滚不生效

审查抓手 ​

PR 审查 grep 三板斧:gorm.DB(层内裸用)、\.Delete((物理删除)、Raw((受限入口)。

相关 ​

小蚂蚁云团队 · 提供技术支持