【问题标题】:How process part of method one request at a time in aspcore如何在asp核心中一次处理方法一个请求的一部分
【发布时间】:2019-02-26 13:35:38
【问题描述】:

我必须增加数据库中的一列,这个增量可以依赖于其他列,例如用户增量,我正在使用 jmeter 同时发送多个请求,我尝试使用锁但不能正常工作,怎么能我冻结了部分方法?

public override DepositoProduto Save(DepositoProduto entity)
    {
        lock (entity)
        {
            using (var transaction = Session.BeginTransaction())
            {
                //here auto increment
                entity.Codigo = All().OrderByDescending(x => x.Codigo).Select(x => x.Codigo).First() + 1;

                //here commit to the database
                transaction.Commit();
            }
        }
        return entity;
    }

【问题讨论】:

  • 您无法锁定entity,因为每次调用此方法时它都可能是不同的实例。创建了一个可以锁定的静态类级别变量。
  • 这有什么例子吗?
  • 我试图创建一个变量私有静态只读对象_lock = new object();添加锁(_lock),但我的所有请求都被冻结,并且不保存
  • 您对号码的实际要求是什么?任何要求它们必须顺序无间隙都会严重限制服务的扩展能力。如果您只需要唯一性,请让数据库使用身份/自动增量/其他方式为您执行此操作。

标签: c# .net asp.net-core concurrency


【解决方案1】:

您需要在单例或静态对象上使用SemaphoreSlim。这可能是您的存储库或其他任何东西,或者如果您需要将其保留在请求范围内,那么您可以使用备用帮助器类来简单地处理这个递增过程。信号量使用起来相当简单。你基本上只是设置了一个静态 ivar,类型为 SemaphoreSlim:

private static SemaphoreSlim _semaphore = new SemaphoreSlim(1);

这里,1 指定一次只能有一个东西进入信号量,这就是您在这个特定场景中想要的。您可以在不同的场景中使用其他数字来基本上限制速率。然后,你包装你需要运行的代码:

_semaphore.Wait(); // or await _semaphore.WaitAsync()

// code protected by semaphore here

_semaphore.Release();

信号量有一个计数器。当Wait 被调用时,信号量将计数器加1,然后如果没有其他等待,它将返回并允许后续代码处理。如果计数器已经高于最大值(这里是 1),那么它不会返回,直到计数器降低到最大阈值以下。该减量通过Release 发生,在您的代码完成后调用。本质上,这创建了一种队列,其他线程等待机会运行受信号量保护的代码。然后,您可以确保一次只有一个 Save 调用正在执行任何操作,因此您的增量事务将始终有效。

它类似于锁定,尤其是计数为 1 时,但信号量是线程安全的,而锁则不是。如果其他东西已经有锁,那么你只会得到一个试图创建锁的异常,你必须通过实现等待和重试模式、断路器等手动恢复。信号量通过不受约束来缓解这种情况任何特定的线程。

【讨论】:

  • 我尝试使用 SemaphoreSlim,但我所有的请求都被冻结,并且不处理
  • 好吧,我只能说你的用法有问题。如果您想使用该代码发布新问题,我或其他人可以查看它。
  • SemaphoreSlim 听起来很完美,请看看ibb.co/mqvhGzF
猜你喜欢
  • 2020-07-12
  • 2017-03-17
  • 1970-01-01
  • 2019-03-30
  • 2019-05-11
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多