【优化】并发下单场景用户金额变动增加事务锁的悲观锁等待模式,防止出现金额异常情况。

This commit is contained in:
大灰灰
2022-08-01 20:15:26 +08:00
parent 4c6ad4c0dc
commit dfa5d5f49c
5 changed files with 120 additions and 51 deletions

View File

@@ -300,6 +300,21 @@ namespace CoreCms.Net.Services
return await BaseDal.QueryByClauseAsync(predicate, orderByPredicate, orderByType, blUseNoLock);
}
/// <summary>
/// 根据条件查询数据(悲观锁等待模式)
/// </summary>
/// <param name="predicate">条件表达式树</param>
/// <param name="orderByPredicate">排序字段</param>
/// <param name="orderByType">排序顺序</param>
/// <param name="blUseTranLock">是否使用TranLock</param>
/// <returns></returns>
public async Task<T> QueryByClauseWithTranLockAsync(Expression<Func<T, bool>> predicate,
Expression<Func<T, object>> orderByPredicate, OrderByType orderByType, bool blUseTranLock = false)
{
return await BaseDal.QueryByClauseWithTranLockAsync(predicate, orderByPredicate, orderByType, blUseTranLock);
}
/// <summary>
/// 写入实体数据
/// </summary>

View File

@@ -64,61 +64,72 @@ namespace CoreCms.Net.Services
if (money != 0)
{
//取用户实际余额
var userInfo = await userServices.QueryByIdAsync(userId);
if (userInfo == null)
try
{
jm.data = jm.code = 11004;
jm.msg = GlobalErrorCodeVars.Code11004;
return jm;
_unitOfWork.BeginTran();
//取用户实际余额
//(会员陌小北提供)
var userInfo = await userServices.QueryByClauseWithTranLockAsync(p => p.id == userId, p => p.id, OrderByType.Desc, true);
if (userInfo == null)
{
jm.data = jm.code = 11004;
jm.msg = GlobalErrorCodeVars.Code11004;
return jm;
}
//取描述,并简单校验
var res = UserHelper.GetMemo(type, money, cateMoney);
if (string.IsNullOrEmpty(res))
{
return jm;
}
var memo = res;
if (type != (int)GlobalEnumVars.UserBalanceSourceTypes.Admin)
{
//后台充值或调不改绝对值
}
//如果是减余额的操作,还是加余额操作
if (type is (int)GlobalEnumVars.UserBalanceSourceTypes.Pay or (int)GlobalEnumVars.UserBalanceSourceTypes.Tocash)
{
money = -money - cateMoney;
}
if (type != (int)GlobalEnumVars.UserBalanceSourceTypes.Service)
{
//后台充值或调不改绝对值
}
var balance = userInfo.balance + money;
if (balance < 0)
{
jm.data = jm.code = 11007;
jm.msg = GlobalErrorCodeVars.Code11007;
return jm;
}
var balanceModel = new CoreCmsUserBalance();
balanceModel.userId = userId;
balanceModel.type = type;
balanceModel.money = money;
balanceModel.balance = balance;
balanceModel.sourceId = sourceId;
balanceModel.memo = memo;
balanceModel.createTime = DateTime.Now;
//增加记录
var balanceModelId = await _dal.InsertAsync(balanceModel);
balanceModel.id = balanceModelId;
//更新用户数据
await userServices.UpdateAsync(p => new CoreCmsUser() { balance = balance }, p => p.id == userId);
jm.data = balanceModel;
_unitOfWork.CommitTran();
}
//取描述,并简单校验
var res = UserHelper.GetMemo(type, money, cateMoney);
if (string.IsNullOrEmpty(res))
catch (Exception e)
{
return jm;
_unitOfWork.RollbackTran();
}
var memo = res;
if (type != (int)GlobalEnumVars.UserBalanceSourceTypes.Admin)
{
//后台充值或调不改绝对值
}
//如果是减余额的操作,还是加余额操作
if (type == (int)GlobalEnumVars.UserBalanceSourceTypes.Pay || type == (int)GlobalEnumVars.UserBalanceSourceTypes.Tocash)
{
money = -money - cateMoney;
}
if (type != (int)GlobalEnumVars.UserBalanceSourceTypes.Service)
{
//后台充值或调不改绝对值
}
var balance = userInfo.balance + money;
if (balance < 0)
{
jm.data = jm.code = 11007;
jm.msg = GlobalErrorCodeVars.Code11007;
return jm;
}
var balanceModel = new CoreCmsUserBalance();
balanceModel.userId = userId;
balanceModel.type = type;
balanceModel.money = money;
balanceModel.balance = balance;
balanceModel.sourceId = sourceId;
balanceModel.memo = memo;
balanceModel.createTime = DateTime.Now;
//增加记录
var balanceModelId = await _dal.InsertAsync(balanceModel);
balanceModel.id = balanceModelId;
//更新用户数据
await userServices.UpdateAsync(p => new CoreCmsUser() { balance = balance }, p => p.id == userId);
jm.data = balanceModel;
}
jm.status = true;