首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >索取优惠券

索取优惠券
EN

Code Review用户
提问于 2017-02-01 20:15:17
回答 3查看 378关注 0票数 3

我目前正在创建一个系统,允许用户要求优惠券,在优惠券被认领后,他们的帐户上的接收货币。

最近我遇到了一个问题,如果两个具有相同优惠券代码的请求在几乎完全相同的时间被触发,我的web服务调用将同时接受这两个请求(可能是因为写入数据库所需的时间)。

有问题的代码:

代码语言:javascript
复制
var userId = User.Identity.GetUserId();

var coupon = Context.Coupons.SingleOrDefault(c => c.Code == code && c.Deleted == false);

if (coupon == null)
    return BadRequest("The code you entered does not belong to a coupon.");

coupon.UserId = userId;
coupon.Deleted = true;

await Context.SaveChangesAsync();

Give the user balance...

return Ok();

My fix:

代码语言:javascript
复制
lock (lockObj)
{
    var userId = User.Identity.GetUserId();

    var coupon = Context.Coupons.SingleOrDefault(c => c.Code == code && c.Deleted == false);

    if (coupon == null)
        return BadRequest("The code you entered does not belong to a coupon.");

    coupon.UserId = userId;
    coupon.Deleted = true;

    Context.SaveChanges();

    Give the user balance...
}

return Ok();

所以我的问题是:这是解决这个问题的合法方法吗?如果很多人同时索取优惠券,恐怕会成为一个问题。有没有更好的方法来解决这个问题?

EN

回答 3

Code Review用户

回答已采纳

发布于 2017-02-01 21:00:26

简单的回答也许是。如果这是唯一更新它的代码,那么您会很好,但是您正在创建一个网关,即使他们有不同的代码,一次只有一个人可以更新。如果您的网站变得很大,您将有性能问题。

如果可能的话,应该让数据库处理并发性。如果使用SQL,则应使用rowversion字段或时间戳字段(如果是旧的SQL )。然后使用TimeStampAttribute配置实体,如果使用fluent,则配置等时标记方法。每当字段被更改时,SQL都会自动更改此值。如果您进行了更新,并且该值发生了更改,那么Entityframe将使用它并抛出一个OptimisticConcurrencyException。您可以捕获该错误,并知道自检索该数据以来数据已发生更改。

票数 4
EN

Code Review用户

发布于 2017-02-02 11:31:56

尝试处理这样的锁定问题可能是个坏主意,因为当侧倾(添加新的服务器/实例)时,这个问题仍然存在。

我建议在SQL中使用并发方法(如@CharlesNRice所建议的),或者使用某种消息队列解决方案,该解决方案旨在处理并发问题。

票数 2
EN

Code Review用户

发布于 2017-02-02 20:16:09

实体框架事务是其内部架构的一部分。"SaveChanges()“方法在事务中操作并保存工作结果。

代码语言:javascript
复制
   using (var context = Context)
   using (var dbcxtransaction = context.Database.BeginTransaction())
   {
                    try
                    {
             //         coupon code here
                        context.SaveChanges();
                        dbcxtransaction.Commit();
                    }
                    catch
                    {
                        dbcxtransaction.Rollback();
                    }
     }
票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/154201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档