签入版本
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
# 12.3 数据访问铁律
|
||||
|
||||
:::tip 必须遵守
|
||||
数据访问的四条红线:**禁止裸用 `*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(`(受限入口)。
|
||||
|
||||
## 相关
|
||||
|
||||
- [3.4 数据访问层(repository)](/zh/guide/repository.html)
|
||||
- [4.8 横切机制](/zh/architecture/cross-cutting.html)
|
||||
- [12.6 数据删除规范](/zh/standards/deletion.html)
|
||||
Reference in New Issue
Block a user