fix: 修复数据库配置和事务一致性问题

数据库配置:
- SQLite 开启 WAL 模式,读写可并发
- 设置 busy_timeout=5000ms 避免锁超时
- 设置 synchronous=NORMAL 平衡性能和安全
- SQLite MaxOpenConns 设为 1 避免并发写入冲突

事务修复:
- auth.go: 注册流程(用户+设备+会话)加入事务
- auth.go: 密码重置(修改密码+标记验证码)加入事务
- cards.go: 卡密使用加入事务,补充 UsedAt 字段
- cards.go: 代理商批量生成(扣款+生成卡密)加入事务
- extension.go: 充值(修改余额+记录)加入事务
- extension.go: 扣费(修改余额+记录)加入事务
- storage_config.go: 设置默认存储加入事务
This commit is contained in:
2026-05-06 08:12:04 +08:00
parent 4841920727
commit 98986b0eb7
5 changed files with 175 additions and 44 deletions
+58 -4
View File
@@ -618,19 +618,36 @@ func handleUseCard(c *gin.Context) {
return
}
tx := database.DB.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
var card model.Card
if err := database.DB.Where("card_key = ?", req.CardKey).First(&card).Error; err != nil {
if err := tx.Where("card_key = ?", req.CardKey).First(&card).Error; err != nil {
tx.Rollback()
response.Error(c, 404, "卡密不存在")
return
}
if card.Status != "unused" {
tx.Rollback()
response.Error(c, 400, "卡密已被使用或已禁用")
return
}
card.Status = "used"
database.DB.Save(&card)
now := time.Now()
card.UsedAt = &now
if err := tx.Save(&card).Error; err != nil {
tx.Rollback()
response.Error(c, 500, "卡密使用失败")
return
}
tx.Commit()
response.Success(c, gin.H{
"message": "卡密使用成功",
@@ -733,13 +750,50 @@ func handleBatchGenerateCards(c *gin.Context) {
return
}
if err := database.DB.Model(&agentUser).Update("balance", agentUser.Balance-totalCost).Error; err != nil {
tx := database.DB.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
if err := tx.Model(&agentUser).Update("balance", agentUser.Balance-totalCost).Error; err != nil {
tx.Rollback()
fmt.Printf("[DEBUG] Update balance error: %v\n", err)
response.Error(c, 500, "扣款失败")
return
}
fmt.Printf("[DEBUG] Balance updated successfully\n")
cards := make([]model.Card, 0, req.Count)
for i := 0; i < req.Count; i++ {
cardKey := req.Prefix + utils.GenerateRandomString(req.Length)
card := model.Card{
ApplicationID: req.ApplicationID,
CardTypeID: req.CardTypeID,
CardKey: cardKey,
CreatorID: effectiveUserID,
Status: "unused",
}
cards = append(cards, card)
}
fmt.Printf("[DEBUG] Generated %d cards, saving to database...\n", len(cards))
if err := tx.Create(&cards).Error; err != nil {
tx.Rollback()
fmt.Printf("[DEBUG] Database create error: %v\n", err)
response.Error(c, 500, "生成卡密失败")
return
}
tx.Commit()
fmt.Printf("[DEBUG] Successfully created %d cards\n", len(cards))
response.Success(c, gin.H{
"message": "批量生成成功",
"count": req.Count,
})
return
}
cards := make([]model.Card, 0, req.Count)