diff --git a/CoreCms.Net.IRepository/IBaseRepository.cs b/CoreCms.Net.IRepository/IBaseRepository.cs index 7170583d..7b01261c 100644 --- a/CoreCms.Net.IRepository/IBaseRepository.cs +++ b/CoreCms.Net.IRepository/IBaseRepository.cs @@ -229,6 +229,18 @@ namespace CoreCms.Net.IRepository Task QueryByClauseAsync(Expression> predicate, Expression> orderByPredicate, OrderByType orderByType, bool blUseNoLock = false); + + /// + /// 根据条件查询数据(悲观锁等待模式) + /// + /// 条件表达式树 + /// 排序字段 + /// 排序顺序 + /// 是否使用TranLock + /// + Task QueryByClauseWithTranLockAsync(Expression> predicate, + Expression> orderByPredicate, OrderByType orderByType, bool blUseTranLock = false); + /// /// 写入实体数据 /// diff --git a/CoreCms.Net.IServices/IBaseServices.cs b/CoreCms.Net.IServices/IBaseServices.cs index 07489178..0d7e1f45 100644 --- a/CoreCms.Net.IServices/IBaseServices.cs +++ b/CoreCms.Net.IServices/IBaseServices.cs @@ -230,6 +230,18 @@ namespace CoreCms.Net.IServices Task QueryByClauseAsync(Expression> predicate, Expression> orderByPredicate, OrderByType orderByType, bool blUseNoLock = false); + /// + /// 根据条件查询数据(悲观锁等待模式) + /// + /// 条件表达式树 + /// 排序字段 + /// 排序顺序 + /// 是否使用TranLock + /// + Task QueryByClauseWithTranLockAsync(Expression> predicate, + Expression> orderByPredicate, OrderByType orderByType, bool blUseTranLock = false); + + /// /// 写入实体数据 /// diff --git a/CoreCms.Net.Repository/BaseRepository.cs b/CoreCms.Net.Repository/BaseRepository.cs index bd96d025..80ee8913 100644 --- a/CoreCms.Net.Repository/BaseRepository.cs +++ b/CoreCms.Net.Repository/BaseRepository.cs @@ -373,6 +373,25 @@ namespace CoreCms.Net.Repository : await DbBaseClient.Queryable().OrderBy(orderByPredicate, orderByType).FirstAsync(predicate); } + + /// + /// 根据条件查询数据(悲观锁等待模式) + /// + /// 条件表达式树 + /// 排序字段 + /// 排序顺序 + /// 是否使用TranLock + /// + public async Task QueryByClauseWithTranLockAsync(Expression> predicate, + Expression> orderByPredicate, OrderByType orderByType, bool blUseTranLock = false) + { + return blUseTranLock + ? await DbBaseClient.Queryable().TranLock(DbLockType.Wait).OrderBy(orderByPredicate, orderByType) + .FirstAsync(predicate) + : await DbBaseClient.Queryable().OrderBy(orderByPredicate, orderByType).FirstAsync(predicate); + } + + /// /// 写入实体数据 /// diff --git a/CoreCms.Net.Services/BaseServices.cs b/CoreCms.Net.Services/BaseServices.cs index 84c8adc1..6083c809 100644 --- a/CoreCms.Net.Services/BaseServices.cs +++ b/CoreCms.Net.Services/BaseServices.cs @@ -300,6 +300,21 @@ namespace CoreCms.Net.Services return await BaseDal.QueryByClauseAsync(predicate, orderByPredicate, orderByType, blUseNoLock); } + + /// + /// 根据条件查询数据(悲观锁等待模式) + /// + /// 条件表达式树 + /// 排序字段 + /// 排序顺序 + /// 是否使用TranLock + /// + public async Task QueryByClauseWithTranLockAsync(Expression> predicate, + Expression> orderByPredicate, OrderByType orderByType, bool blUseTranLock = false) + { + return await BaseDal.QueryByClauseWithTranLockAsync(predicate, orderByPredicate, orderByType, blUseTranLock); + } + /// /// 写入实体数据 /// diff --git a/CoreCms.Net.Services/User/CoreCmsUserBalanceServices.cs b/CoreCms.Net.Services/User/CoreCmsUserBalanceServices.cs index 07da2b4a..210d007b 100644 --- a/CoreCms.Net.Services/User/CoreCmsUserBalanceServices.cs +++ b/CoreCms.Net.Services/User/CoreCmsUserBalanceServices.cs @@ -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;