fix(fin): 激活配置并发行锁保护 FIN-03
- commission_withdrawal_setting/service.go: 激活事务内首步加 FOR UPDATE 行锁,防止并发时出现多条 is_active=true - wechat_config_store.go: ActivateInTx 激活前同样加行锁保护
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||||
"github.com/break/junhong_cmp_fiber/pkg/middleware"
|
"github.com/break/junhong_cmp_fiber/pkg/middleware"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/clause"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
@@ -47,6 +48,12 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateWithdrawalSettingRe
|
|||||||
setting.Updater = currentUserID
|
setting.Updater = currentUserID
|
||||||
|
|
||||||
err := s.db.Transaction(func(tx *gorm.DB) error {
|
err := s.db.Transaction(func(tx *gorm.DB) error {
|
||||||
|
// 先锁定当前活跃记录,防止并发激活导致多条 is_active=true
|
||||||
|
var current model.CommissionWithdrawalSetting
|
||||||
|
tx.WithContext(ctx).Clauses(clause.Locking{Strength: "UPDATE"}).
|
||||||
|
Where("is_active = ?", true).
|
||||||
|
First(¤t)
|
||||||
|
|
||||||
if err := s.commissionWithdrawalSettingStore.DeactivateCurrentWithTx(ctx, tx); err != nil {
|
if err := s.commissionWithdrawalSettingStore.DeactivateCurrentWithTx(ctx, tx); err != nil {
|
||||||
return errors.Wrap(errors.CodeInternalError, err, "失效旧配置失败")
|
return errors.Wrap(errors.CodeInternalError, err, "失效旧配置失败")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/break/junhong_cmp_fiber/internal/store"
|
"github.com/break/junhong_cmp_fiber/internal/store"
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/clause"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WechatConfigStore 微信参数配置数据访问层
|
// WechatConfigStore 微信参数配置数据访问层
|
||||||
@@ -100,6 +101,12 @@ func (s *WechatConfigStore) GetActive(ctx context.Context) (*model.WechatConfig,
|
|||||||
|
|
||||||
// ActivateInTx 在事务内激活指定配置(先停用所有,再激活指定记录)
|
// ActivateInTx 在事务内激活指定配置(先停用所有,再激活指定记录)
|
||||||
func (s *WechatConfigStore) ActivateInTx(ctx context.Context, tx *gorm.DB, id uint) error {
|
func (s *WechatConfigStore) ActivateInTx(ctx context.Context, tx *gorm.DB, id uint) error {
|
||||||
|
// 先锁定当前活跃记录,防止并发激活导致多条 is_active=true
|
||||||
|
var current model.WechatConfig
|
||||||
|
tx.WithContext(ctx).Clauses(clause.Locking{Strength: "UPDATE"}).
|
||||||
|
Where("is_active = ?", true).
|
||||||
|
First(¤t)
|
||||||
|
|
||||||
// 先停用所有激活的配置
|
// 先停用所有激活的配置
|
||||||
if err := tx.WithContext(ctx).Model(&model.WechatConfig{}).
|
if err := tx.WithContext(ctx).Model(&model.WechatConfig{}).
|
||||||
Where("is_active = ?", true).
|
Where("is_active = ?", true).
|
||||||
|
|||||||
Reference in New Issue
Block a user