我必须在数据库中增加一列,该增加可以依赖于其他列,例如由用户增加,我使用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;
}
答案 0 :(得分:0)
您需要在单例作用域或静态对象上使用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时,但信号量是线程安全的,而锁则不是。如果其他东西已经具有锁,那么您将简单地尝试创建该锁,并通过实现等待和重试模式,断路器等来手动恢复。信号量通过不绑定到任何特定的线程。