diff --git a/CoreCms.Net.IRepository/IBaseRepository.cs b/CoreCms.Net.IRepository/IBaseRepository.cs
index 24658ace..9c20039c 100644
--- a/CoreCms.Net.IRepository/IBaseRepository.cs
+++ b/CoreCms.Net.IRepository/IBaseRepository.cs
@@ -246,8 +246,10 @@ namespace CoreCms.Net.IRepository
/// 是否使用WITH(NoLock)
/// 是否启用缓存
/// 缓存时长(分钟)
+ /// 是否使用锁
+ /// 数据锁类型
///
- Task QueryByClauseAsync(Expression> predicate, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue);
+ Task QueryByClauseAsync(Expression> predicate, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue, bool blUseTranLock = false, DbLockType dbLockType = DbLockType.Wait);
///
/// 根据条件查询数据
@@ -271,23 +273,10 @@ namespace CoreCms.Net.IRepository
/// 是否使用WITH(NoLock)
/// 是否启用缓存
/// 缓存时长(分钟)
+ /// 是否使用锁
+ /// 数据锁类型
///
- Task QueryByClauseAsync(Expression> predicate, Expression> orderByPredicate,
- OrderByType orderByType, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue);
-
-
- ///
- /// 根据条件查询数据(悲观锁等待模式)
- ///
- /// 条件表达式树
- /// 排序字段
- /// 排序顺序
- /// 是否使用TranLock
- /// 是否启用缓存
- /// 缓存时长(分钟)
- ///
- Task QueryByClauseWithTranLockAsync(Expression> predicate,
- Expression> orderByPredicate, OrderByType orderByType, bool blUseTranLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue);
+ Task QueryByClauseAsync(Expression> predicate, Expression> orderByPredicate, OrderByType orderByType, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue, bool blUseTranLock = false, DbLockType dbLockType = DbLockType.Wait);
#endregion
diff --git a/CoreCms.Net.IServices/IBaseServices.cs b/CoreCms.Net.IServices/IBaseServices.cs
index 0493d945..c3feca67 100644
--- a/CoreCms.Net.IServices/IBaseServices.cs
+++ b/CoreCms.Net.IServices/IBaseServices.cs
@@ -247,8 +247,10 @@ namespace CoreCms.Net.IServices
/// 是否使用WITH(NoLock)
/// 是否启用缓存
/// 缓存时长(分钟)
+ /// 是否使用锁
+ /// 数据锁类型
///
- Task QueryByClauseAsync(Expression> predicate, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue);
+ Task QueryByClauseAsync(Expression> predicate, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue, bool blUseTranLock = false, DbLockType dbLockType = DbLockType.Wait);
///
/// 根据条件查询数据
@@ -272,24 +274,12 @@ namespace CoreCms.Net.IServices
/// 是否使用WITH(NoLock)
/// 是否启用缓存
/// 缓存时长(分钟)
+ /// 是否使用锁
+ /// 数据锁类型
///
- Task QueryByClauseAsync(Expression> predicate, Expression> orderByPredicate,
- OrderByType orderByType, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue);
+ Task QueryByClauseAsync(Expression> predicate, Expression> orderByPredicate, OrderByType orderByType, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue, bool blUseTranLock = false, DbLockType dbLockType = DbLockType.Wait);
- ///
- /// 根据条件查询数据(悲观锁等待模式)
- ///
- /// 条件表达式树
- /// 排序字段
- /// 排序顺序
- /// 是否使用TranLock
- /// 是否启用缓存
- /// 缓存时长(分钟)
- ///
- Task QueryByClauseWithTranLockAsync(Expression> predicate,
- Expression> orderByPredicate, OrderByType orderByType, bool blUseTranLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue);
-
#endregion
#region 新闻数据
diff --git a/CoreCms.Net.Repository/BaseRepository.cs b/CoreCms.Net.Repository/BaseRepository.cs
index 0315e4c2..30e47833 100644
--- a/CoreCms.Net.Repository/BaseRepository.cs
+++ b/CoreCms.Net.Repository/BaseRepository.cs
@@ -364,13 +364,12 @@ namespace CoreCms.Net.Repository
/// 是否使用WITH(NoLock)
/// 是否启用缓存
/// 缓存时长(分钟)
+ /// 是否使用锁
+ /// 数据锁类型
///
- public async Task QueryByClauseAsync(Expression> predicate, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue)
+ public async Task QueryByClauseAsync(Expression> predicate, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue, bool blUseTranLock = false, DbLockType dbLockType = DbLockType.Wait)
{
- return await DbBaseClient.Queryable()
- .WithNoLockOrNot(blUseNoLock)
- .WithCacheIF(isDataCache, cacheTimes)
- .FirstAsync(predicate);
+ return await DbBaseClient.Queryable().WithNoLockOrNot(blUseNoLock).WithUseTranLockOrNot(blUseTranLock, dbLockType).WithCacheIF(isDataCache, cacheTimes).FirstAsync(predicate);
}
///
@@ -397,27 +396,14 @@ namespace CoreCms.Net.Repository
/// 是否使用WITH(NoLock)
/// 是否启用缓存
/// 缓存时长(分钟)
+ /// 是否使用锁
+ /// 数据锁类型
///
- public async Task QueryByClauseAsync(Expression> predicate, Expression> orderByPredicate, OrderByType orderByType, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue)
+ public async Task QueryByClauseAsync(Expression> predicate, Expression> orderByPredicate, OrderByType orderByType, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue, bool blUseTranLock = false, DbLockType dbLockType = DbLockType.Wait)
{
- return await DbBaseClient.Queryable().OrderBy(orderByPredicate, orderByType).WithNoLockOrNot(blUseNoLock).WithCacheIF(isDataCache, cacheTimes).FirstAsync(predicate);
+ return await DbBaseClient.Queryable().OrderBy(orderByPredicate, orderByType).WithNoLockOrNot(blUseNoLock).WithUseTranLockOrNot(blUseTranLock, dbLockType).WithCacheIF(isDataCache, cacheTimes).FirstAsync(predicate);
}
-
- ///
- /// 根据条件查询数据(悲观锁等待模式)
- ///
- /// 条件表达式树
- /// 排序字段
- /// 排序顺序
- /// 是否使用TranLock
- /// 是否启用缓存
- /// 缓存时长(分钟)
- ///
- public async Task QueryByClauseWithTranLockAsync(Expression> predicate, Expression> orderByPredicate, OrderByType orderByType, bool blUseTranLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue)
- {
- return await DbBaseClient.Queryable().TranLock(DbLockType.Wait).OrderBy(orderByPredicate, orderByType).WithCacheIF(isDataCache, cacheTimes).FirstAsync(predicate);
- }
#endregion
#region 新增数据
diff --git a/CoreCms.Net.Repository/SqlSugarExtensions.cs b/CoreCms.Net.Repository/SqlSugarExtensions.cs
index f725dcd3..23b9ccc1 100644
--- a/CoreCms.Net.Repository/SqlSugarExtensions.cs
+++ b/CoreCms.Net.Repository/SqlSugarExtensions.cs
@@ -14,6 +14,23 @@ namespace CoreCms.Net.Repository
return query;
}
+ ///
+ /// 是否启用锁
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ internal static ISugarQueryable WithUseTranLockOrNot(this ISugarQueryable query, bool @lock = false, DbLockType dbLockType = DbLockType.Wait)
+ {
+ if (@lock)
+ {
+ query = query.TranLock(dbLockType);
+ }
+
+ return query;
+ }
}
}
diff --git a/CoreCms.Net.Services/BaseServices.cs b/CoreCms.Net.Services/BaseServices.cs
index d1b33d52..52ce222b 100644
--- a/CoreCms.Net.Services/BaseServices.cs
+++ b/CoreCms.Net.Services/BaseServices.cs
@@ -298,10 +298,12 @@ namespace CoreCms.Net.Services
/// 是否使用WITH(NoLock)
/// 是否启用缓存
/// 缓存时长(分钟)
+ /// 是否使用锁
+ /// 数据锁类型
///
- public async Task QueryByClauseAsync(Expression> predicate, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue)
+ public async Task QueryByClauseAsync(Expression> predicate, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue, bool blUseTranLock = false, DbLockType dbLockType = DbLockType.Wait)
{
- return await BaseDal.QueryByClauseAsync(predicate, blUseNoLock, isDataCache, cacheTimes);
+ return await BaseDal.QueryByClauseAsync(predicate, blUseNoLock, isDataCache, cacheTimes, blUseTranLock, dbLockType);
}
///
@@ -329,28 +331,15 @@ namespace CoreCms.Net.Services
/// 是否使用WITH(NoLock)
/// 是否启用缓存
/// 缓存时长(分钟)
+ /// 是否使用锁
+ /// 数据锁类型
///
- public async Task QueryByClauseAsync(Expression> predicate, Expression> orderByPredicate, OrderByType orderByType, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue)
+ public async Task QueryByClauseAsync(Expression> predicate, Expression> orderByPredicate, OrderByType orderByType, bool blUseNoLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue, bool blUseTranLock = false, DbLockType dbLockType = DbLockType.Wait)
{
- return await BaseDal.QueryByClauseAsync(predicate, orderByPredicate, orderByType, blUseNoLock, isDataCache, cacheTimes);
+ return await BaseDal.QueryByClauseAsync(predicate, orderByPredicate, orderByType, blUseNoLock, isDataCache, cacheTimes, blUseTranLock, dbLockType);
}
- ///
- /// 根据条件查询数据(悲观锁等待模式)
- ///
- /// 条件表达式树
- /// 排序字段
- /// 排序顺序
- /// 是否使用TranLock
- /// 是否启用缓存
- /// 缓存时长(分钟)
- ///
- public async Task QueryByClauseWithTranLockAsync(Expression> predicate, Expression> orderByPredicate, OrderByType orderByType, bool blUseTranLock = false, bool isDataCache = false, int cacheTimes = int.MaxValue)
- {
- return await BaseDal.QueryByClauseWithTranLockAsync(predicate, orderByPredicate, orderByType, blUseTranLock, isDataCache, cacheTimes);
- }
-
#endregion
#region 插入数据
diff --git a/CoreCms.Net.Services/Promotion/CoreCmsPromotionServices.cs b/CoreCms.Net.Services/Promotion/CoreCmsPromotionServices.cs
index 46f1232f..b04aa66f 100644
--- a/CoreCms.Net.Services/Promotion/CoreCmsPromotionServices.cs
+++ b/CoreCms.Net.Services/Promotion/CoreCmsPromotionServices.cs
@@ -694,7 +694,7 @@ 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;
diff --git a/CoreCms.Net.Web.WebApi/Controllers/CouponController.cs b/CoreCms.Net.Web.WebApi/Controllers/CouponController.cs
index 7ed8e2e9..270b212b 100644
--- a/CoreCms.Net.Web.WebApi/Controllers/CouponController.cs
+++ b/CoreCms.Net.Web.WebApi/Controllers/CouponController.cs
@@ -14,6 +14,7 @@ using System.Threading.Tasks;
using CoreCms.Net.Auth.HttpContextUser;
using CoreCms.Net.Caching.AutoMate.RedisCache;
using CoreCms.Net.Configuration;
+using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.FromBody;
@@ -35,18 +36,19 @@ namespace CoreCms.Net.Web.WebApi.Controllers
private readonly ICoreCmsCouponServices _couponServices;
private readonly ICoreCmsPromotionServices _promotionServices;
private readonly IRedisOperationRepository _redisOperationRepository;
-
+ private readonly IUnitOfWork _unionOfWork;
///
/// 构造函数
///
public CouponController(IHttpContextUser user
- , ICoreCmsCouponServices couponServices, ICoreCmsPromotionServices promotionServices, IRedisOperationRepository redisOperationRepository)
+ , ICoreCmsCouponServices couponServices, ICoreCmsPromotionServices promotionServices, IRedisOperationRepository redisOperationRepository, IUnitOfWork unionOfWork)
{
_user = user;
_couponServices = couponServices;
_promotionServices = promotionServices;
_redisOperationRepository = redisOperationRepository;
+ _unionOfWork = unionOfWork;
}
//公共接口====================================================================================================
@@ -225,25 +227,50 @@ namespace CoreCms.Net.Web.WebApi.Controllers
return jm;
}
- //判断优惠券是否可以领取?
- var promotionModel = await _promotionServices.ReceiveCoupon(coupon.promotionId);
- if (promotionModel.status == false)
+ try
{
- return promotionModel;
- }
- //判断用户是否已领取?
- if (promotionModel.data is CoreCmsPromotion { maxNums: > 0 } info)
- {
- //判断用户是否已领取?领取次数
- var couponResult = await _couponServices.GetMyCoupon(_user.ID, coupon.promotionId, "all", 1, 9999);
- if (couponResult.status && couponResult.code > info.maxNums)
+ _unionOfWork.BeginTran();
+
+ //判断优惠券是否可以领取?
+ var promotionModel = await _promotionServices.ReceiveCoupon(coupon.promotionId);
+ 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, coupon.promotionId, "all", 1, 9999);
+ if (couponResult.status && couponResult.code >= promotion.maxNums)
+ {
+ _unionOfWork.RollbackTran();
+ jm.msg = GlobalErrorCodeVars.Code15018;
+ return jm;
+ }
+ }
+ jm = await _couponServices.ReceiveCoupon(_user.ID, entity.key);
+
+ _unionOfWork.CommitTran();
+
+ jm.otherData = promotionModel;
+
+ }
+ catch (Exception e)
+ {
+ _unionOfWork.RollbackTran();
+ jm.msg = GlobalErrorCodeVars.Code10000;
+ jm.data = e;
}
- //
- jm = await _couponServices.ReceiveCoupon(_user.ID, entity.key);
return jm;
}