领取优惠券开启事务,并在查询优惠券信息时加update锁解决并发领优惠券产生超买问题。

修复优惠券领取数量设置为0时,没有返回错误
pull/214/head
JunFeng Wu 2 years ago
parent 110de1d2a7
commit 7d7e408ddb

@ -203,8 +203,11 @@ namespace CoreCms.Net.IRepository
/// </summary>
/// <param name="predicate">条件表达式树</param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <param name="blUseTranLock">是否使用事务锁</param>
/// <param name="dbLockType">事务锁类型</param>
/// <returns></returns>
Task<T> QueryByClauseAsync(Expression<Func<T, bool>> predicate, bool blUseNoLock = false);
Task<T> QueryByClauseAsync(Expression<Func<T, bool>> predicate, bool blUseNoLock = false,bool blUseTranLock = false,
DbLockType dbLockType = DbLockType.Wait);
/// <summary>
/// 根据条件查询数据

@ -331,12 +331,16 @@ namespace CoreCms.Net.Repository
/// </summary>
/// <param name="predicate">条件表达式树</param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <param name="blUseTranLock">是否使用事务锁</param>
/// <param name="dbLockType">事务锁类型</param>
/// <returns></returns>
public async Task<T> QueryByClauseAsync(Expression<Func<T, bool>> predicate, bool blUseNoLock = false)
public async Task<T> QueryByClauseAsync(Expression<Func<T, bool>> predicate, bool blUseNoLock = false,bool blUseTranLock = false,
DbLockType dbLockType = DbLockType.Wait)
{
return blUseNoLock
? await DbBaseClient.Queryable<T>().With(SqlWith.NoLock).FirstAsync(predicate)
: await DbBaseClient.Queryable<T>().FirstAsync(predicate);
: (blUseTranLock? await DbBaseClient.Queryable<T>().TranLock(dbLockType).FirstAsync(predicate)
: await DbBaseClient.Queryable<T>().FirstAsync(predicate));
}
/// <summary>

@ -465,16 +465,17 @@ namespace CoreCms.Net.Services
where = where.And(p => p.isDel == false); //是否被删除
var info = await _dal.QueryByClauseAsync(where);
var info = await _dal.QueryByClauseAsync(where,false,true);
if (info != null)
{
jm.data = info;
//判断最大领取数量
if (info.maxRecevieNums == 0)
{
jm.status = true;
jm.status = false;
return jm;
}
var receiveCount = await _couponServices.GetCountAsync(p => p.promotionId == promotionId);
if (receiveCount >= info.maxRecevieNums)
{

@ -13,6 +13,7 @@ using System.Linq;
using System.Threading.Tasks;
using CoreCms.Net.Auth.HttpContextUser;
using CoreCms.Net.Configuration;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.FromBody;
@ -33,18 +34,21 @@ namespace CoreCms.Net.Web.WebApi.Controllers
private readonly IHttpContextUser _user;
private readonly ICoreCmsCouponServices _couponServices;
private readonly ICoreCmsPromotionServices _promotionServices;
private readonly IUnitOfWork _unionOfWork;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="user"></param>
/// <param name="couponServices"></param>
/// <param name="promotionServices"></param>
/// <param name="unionOfWork"></param>
public CouponController(IHttpContextUser user
, ICoreCmsCouponServices couponServices, ICoreCmsPromotionServices promotionServices)
, ICoreCmsCouponServices couponServices, ICoreCmsPromotionServices promotionServices, IUnitOfWork unionOfWork)
{
_user = user;
_couponServices = couponServices;
_promotionServices = promotionServices;
_unionOfWork = unionOfWork;
}
//公共接口====================================================================================================
@ -144,32 +148,55 @@ namespace CoreCms.Net.Web.WebApi.Controllers
jm.msg = GlobalErrorCodeVars.Code15006;
return jm;
}
//判断优惠券是否可以领取?
var promotionModel = await _promotionServices.ReceiveCoupon(entity.id);
if (promotionModel.status == false)
try
{
return promotionModel;
}
_unionOfWork.BeginTran();
var promotion = (CoreCmsPromotion)promotionModel.data;
if (promotion == null)
{
jm.msg = GlobalErrorCodeVars.Code15019;
return jm;
}
if (promotion.maxNums > 0)
{
//判断用户是否已领取?领取次数
var couponResult = await _couponServices.GetMyCoupon(_user.ID, entity.id, "all", 1, 9999);
if (couponResult.status && couponResult.code >= promotion.maxNums)
//判断优惠券是否可以领取?
var promotionModel = await _promotionServices.ReceiveCoupon(entity.id);
if (promotionModel.status == false)
{
jm.msg = GlobalErrorCodeVars.Code15018;
_unionOfWork.RollbackTran();
return promotionModel;
}
var promotion = (CoreCmsPromotion)promotionModel.data;
if (promotion == null)
{
_unionOfWork.RollbackTran();
jm.msg = GlobalErrorCodeVars.Code15019;
return jm;
}
if (promotion.maxNums > 0)
{
//判断用户是否已领取?领取次数
var couponResult = await _couponServices.GetMyCoupon(_user.ID, entity.id, "all", 1, 9999);
if (couponResult.status && couponResult.code >= promotion.maxNums)
{
_unionOfWork.RollbackTran();
jm.msg = GlobalErrorCodeVars.Code15018;
return jm;
}
}
jm = await _couponServices.AddData(_user.ID, entity.id, promotion);
_unionOfWork.CommitTran();
jm.otherData = promotionModel;
}
catch (Exception e)
{
_unionOfWork.RollbackTran();
jm.msg = GlobalErrorCodeVars.Code10000;
}
jm = await _couponServices.AddData(_user.ID, entity.id, promotion);
jm.otherData = promotionModel;
return jm;
}
#endregion

Loading…
Cancel
Save