# 文件上传策略分析
## 🎯 业界成熟方案:先上传OSS,再存数据库
### 方案对比
| 方案 | 优点 | 缺点 | 适用场景 |
|------|------|------|----------|
| **先上传OSS,再存数据库** ✅ | 1. OSS上传失败不影响数据库
2. 数据库事务可快速回滚
3. 用户体验好(文件已上传)
4. 孤立文件可定时清理 | 1. 数据库失败会产生孤立文件
2. 需要清理机制 | **推荐方案**(业界主流) |
| 先存数据库,再上传OSS | 1. 数据库失败不会上传OSS
2. 不会产生孤立文件 | 1. OSS上传失败需要回滚数据库
2. 数据库事务时间长
3. 用户体验差 | 不推荐 |
### 为什么选择"先上传OSS,再存数据库"?
1. **性能优势**
- OSS上传是外部服务调用,不应该阻塞数据库事务
- 数据库事务时间短,减少锁竞争
2. **可靠性优势**
- OSS上传失败,直接返回错误,不产生脏数据
- 数据库保存失败,OSS文件可以后续清理(定时任务)
3. **用户体验优势**
- 文件已上传成功,即使数据库失败,文件还在
- 可以重试数据库保存,无需重新上传
4. **业界实践**
- 阿里云、腾讯云、AWS 等主流云服务都推荐此方案
- 大多数开源项目采用此方案
### 当前实现方案
```
1. 校验(文件分类、配额)
↓
2. 读取文件内容
↓
3. 上传到OSS(FileService.createFile)
- 成功:返回 fileUrl 和 filePath
- 失败:直接抛出异常,不保存数据库
↓
4. 保存数据库(事务中)
- 成功:返回文件ID
- 失败:删除OSS文件,抛出异常
↓
5. 更新配额
```
### 异常处理
1. **OSS上传失败**
- 直接抛出异常,不保存数据库
- 用户可重试上传
2. **数据库保存失败**
- 删除已上传的OSS文件(清理)
- 抛出异常,用户可重试
3. **孤立文件清理**
- 定时任务清理未关联数据库的OSS文件
- 基于 infra_file 表的创建时间判断
### 优化建议
1. **异步清理孤立文件**
- 定时任务扫描 infra_file 表
- 删除超过7天未关联 tik_user_file 的文件
2. **重试机制**
- 数据库保存失败时,记录重试队列
- 后台任务重试保存
3. **监控告警**
- 监控OSS上传失败率
- 监控数据库保存失败率
- 监控孤立文件数量