C# 同时更新数据库中计数器值的正确方法?

C# 同时更新数据库中计数器值的正确方法?,c#,sql-server,multithreading,transactions,deadlock,C#,Sql Server,Multithreading,Transactions,Deadlock,问题: 我有一个多线程应用程序或多个客户端应用程序需要访问存储在数据库中的计数器。他们需要读取值,然后向计数器输入+1,然后再次存储。在读写过程中,有一个额外的逻辑层,其中计数器值与外部获得的输入进行比较,逻辑结果指示是否向计数器加1 伪代码: var counter = Database.GetCurrentValueOfCounter(); counter = max(counter, input); Database.Save(counter + 1); return counter

问题:

我有一个多线程应用程序或多个客户端应用程序需要访问存储在数据库中的计数器。他们需要读取值,然后向计数器输入+1,然后再次存储。在读写过程中,有一个额外的逻辑层,其中计数器值与外部获得的输入进行比较,逻辑结果指示是否向计数器加1

伪代码:

var counter = Database.GetCurrentValueOfCounter();

counter = max(counter, input);

Database.Save(counter + 1);

return counter;
例如,在多客户机场景中,所有客户机都从外部获得一个输入,因为它们是同时获得的,所以都等于相同的值

当第一个客户端进入此函数时,其他客户端应等待计数器更新后再进入。因此,对于上述场景中的多个客户端,每个客户端将获得一个顺序计数器值

我试过的

我使用c EF Core来实现代码和数据库逻辑。我已尝试通过Database.beginTransactionSolationLevel.Serializable使用可序列化事务

然后从表->c中的逻辑->更新表设置计数器中选择计数器

然而,这种方法给了我一个死锁事务。研究死锁,我认为死锁发生在第二个线程SELECT语句上,这是有意义的,因为第一个线程将在事务中锁定它

问题:

在数据库级别实现这种锁定/队列机制的正确方法是什么

目前,我已经求助于通过lockobject在代码中输入一个关键部分,但是,在多服务器场景中,这将失败。我可以研究使用SQL分布式锁,但是,在应用程序级别执行锁感觉不太正确


有人能告诉我如何在数据库级别实现这种顺序锁定吗?

这就是为什么Identityexists@nbk请详细说明一下好吗?每个cpu都可以根据自己的需要重新排序命令fpr a rdms,所以唯一能确保的方法是设置一个自动增量,使其处于较低的级别。这需要我每次插入新行。此外,它没有考虑外部逻辑:maxcounter,input。输入可能远大于当前计数器,在这种情况下,当前计数器跳到输入。您可以更新数据库,并使用原子更新查询返回新值,如update dbo.CustomCounter SET CounterValue=case WHEN CounterValue>@InputValue然后CounterValue ELSE@InputValue END+1 OUTPUT inserted.CounterValue;