修复余额与套餐用量并发更新可能导致数据错误的问题
This commit is contained in:
@@ -1,8 +1,5 @@
|
|||||||
## todo
|
## todo
|
||||||
|
|
||||||
|
|
||||||
- 统一简化包导入别名
|
|
||||||
- 修改 postgres 默认事务级别到 RR
|
|
||||||
- 撤销令牌需要改成用户权限,只有本人可以撤销
|
- 撤销令牌需要改成用户权限,只有本人可以撤销
|
||||||
- 移动端适配
|
- 移动端适配
|
||||||
- 扩展 device 权限验证方式,提供一种方法区分内部和外部服务
|
- 扩展 device 权限验证方式,提供一种方法区分内部和外部服务
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -244,6 +245,8 @@ func (s *channelService) CreateChannel(
|
|||||||
count int,
|
count int,
|
||||||
nodeFilter ...NodeFilterConfig,
|
nodeFilter ...NodeFilterConfig,
|
||||||
) ([]*PortInfo, error) {
|
) ([]*PortInfo, error) {
|
||||||
|
var now = time.Now()
|
||||||
|
|
||||||
var step = time.Now()
|
var step = time.Now()
|
||||||
var rid = ctx.Value(requestid.ConfigDefault.ContextKey).(string)
|
var rid = ctx.Value(requestid.ConfigDefault.ContextKey).(string)
|
||||||
|
|
||||||
@@ -298,7 +301,6 @@ func (s *channelService) CreateChannel(
|
|||||||
// 分配端口
|
// 分配端口
|
||||||
step = time.Now()
|
step = time.Now()
|
||||||
|
|
||||||
now := time.Now()
|
|
||||||
expiration := common.LocalDateTime(now.Add(time.Duration(resource.Live) * time.Second))
|
expiration := common.LocalDateTime(now.Add(time.Duration(resource.Live) * time.Second))
|
||||||
_addr, channels, err := assignPort(q, edgeAssigns, auth.Payload.Id, protocol, authType, expiration, filter)
|
_addr, channels, err := assignPort(q, edgeAssigns, auth.Payload.Id, protocol, authType, expiration, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -315,7 +317,7 @@ func (s *channelService) CreateChannel(
|
|||||||
Used: resource.Used + int32(count),
|
Used: resource.Used + int32(count),
|
||||||
DailyLast: common.LocalDateTime(now),
|
DailyLast: common.LocalDateTime(now),
|
||||||
}
|
}
|
||||||
last := time.Time(resource.DailyLast)
|
var last = time.Time(resource.DailyLast)
|
||||||
if now.Year() != last.Year() || now.Month() != last.Month() || now.Day() != last.Day() {
|
if now.Year() != last.Year() || now.Month() != last.Month() || now.Day() != last.Day() {
|
||||||
toUpdate.DailyUsed = int32(count)
|
toUpdate.DailyUsed = int32(count)
|
||||||
} else {
|
} else {
|
||||||
@@ -346,7 +348,7 @@ func (s *channelService) CreateChannel(
|
|||||||
slog.Debug("缓存通道数据", "rid", rid, "step", time.Since(step))
|
slog.Debug("缓存通道数据", "rid", rid, "step", time.Since(step))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}, &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -674,7 +676,7 @@ func assignPort(
|
|||||||
q.Channel.NodeHost,
|
q.Channel.NodeHost,
|
||||||
q.Channel.DeletedAt,
|
q.Channel.DeletedAt,
|
||||||
).
|
).
|
||||||
Save(channels...)
|
Create(channels...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"platform/pkg/rds"
|
"platform/pkg/rds"
|
||||||
@@ -162,13 +163,13 @@ func (s *resourceService) CreateResource(data *CreateResourceData, uid int32) er
|
|||||||
// 更新用户余额
|
// 更新用户余额
|
||||||
_, err = q.User.
|
_, err = q.User.
|
||||||
Where(q.User.ID.Eq(uid)).
|
Where(q.User.ID.Eq(uid)).
|
||||||
Update(q.User.Balance, user.Balance-amount)
|
UpdateSimple(q.User.Balance.Sub(amount))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}, &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ func (s *userService) RechargeConfirm(ctx context.Context, tradeNo string, verif
|
|||||||
|
|
||||||
_, err = tx.User.
|
_, err = tx.User.
|
||||||
Where(tx.User.ID.Eq(user.ID)).
|
Where(tx.User.ID.Eq(user.ID)).
|
||||||
Update(tx.User.Balance, user.Balance+result.Trade.Amount)
|
UpdateSimple(tx.User.Balance.Add(result.Trade.Amount))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user