fix: 删稿扣域能增加一致性保障(事务包裹 + 有限重试)
- DeductOnDeletePost 使用 DB 事务包裹 AddEnergy + CreateEnergyLog,确保扣域能写流水原子性 - Controller 层增加 3 次指数退避重试(100ms/200ms/400ms),全部失败后 log.Printf 记录 - 保持原行为:扣减无视负数,失败不阻塞删稿主流程
This commit is contained in:
@ -1,8 +1,10 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"metazone.cc/metalab/internal/common"
|
"metazone.cc/metalab/internal/common"
|
||||||
"metazone.cc/metalab/internal/model"
|
"metazone.cc/metalab/internal/model"
|
||||||
@ -349,9 +351,21 @@ func (ctrl *StudioController) Delete(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删稿扣作者域能(无视负数,静默失败)
|
// 删稿扣作者域能(无视负数,有限重试后静默忽略)
|
||||||
if ctrl.energySvc != nil {
|
if ctrl.energySvc != nil {
|
||||||
_ = ctrl.energySvc.DeductOnDeletePost(authorID, uint(id))
|
const maxRetries = 3
|
||||||
|
backoff := 100 * time.Millisecond
|
||||||
|
for i := 0; i < maxRetries; i++ {
|
||||||
|
if err := ctrl.energySvc.DeductOnDeletePost(authorID, uint(id)); err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if i < maxRetries-1 {
|
||||||
|
time.Sleep(backoff)
|
||||||
|
backoff *= 2
|
||||||
|
} else {
|
||||||
|
log.Printf("删稿扣域能失败(user=%d, post=%d): %v", authorID, id, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
common.OkMessage(c, "删除成功")
|
common.OkMessage(c, "删除成功")
|
||||||
|
|||||||
@ -254,8 +254,12 @@ func (s *EnergyService) RefundOnRenameReject(userID uint) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DeductOnDeletePost 删稿扣域能(扣文章作者的域能,无视负数)
|
// DeductOnDeletePost 删稿扣域能(扣文章作者的域能,无视负数)
|
||||||
|
// 事务包裹:确保扣域能 + 写流水原子性
|
||||||
func (s *EnergyService) DeductOnDeletePost(authorUserID uint, postID uint) error {
|
func (s *EnergyService) DeductOnDeletePost(authorUserID uint, postID uint) error {
|
||||||
if err := s.repo.AddEnergy(authorUserID, EnergyDeletePost); err != nil {
|
return s.db.Transaction(func(tx *gorm.DB) error {
|
||||||
|
txRepo := s.repo.WithTx(tx)
|
||||||
|
|
||||||
|
if err := txRepo.AddEnergy(authorUserID, EnergyDeletePost); err != nil {
|
||||||
return fmt.Errorf("扣减删稿域能失败: %w", err)
|
return fmt.Errorf("扣减删稿域能失败: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +271,8 @@ func (s *EnergyService) DeductOnDeletePost(authorUserID uint, postID uint) error
|
|||||||
RelatedID: postID,
|
RelatedID: postID,
|
||||||
Description: "删除文章消耗 2.0 域能",
|
Description: "删除文章消耗 2.0 域能",
|
||||||
}
|
}
|
||||||
return s.repo.CreateEnergyLog(log)
|
return txRepo.CreateEnergyLog(log)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// AdminAdjust 后台调整用户域能
|
// AdminAdjust 后台调整用户域能
|
||||||
|
|||||||
Reference in New Issue
Block a user