如何锁定SQL Server中尚不存在的特定行

时间:2018-04-04 22:34:36

标签: sql sql-server database multithreading database-design

我有一个API速率限制表,我正在为我们的某个应用程序管理。这是它的定义。

CREATE TABLE [dbo].[RateLimit]
(
    [UserId] [int] NOT NULL,
    [EndPointId] [smallint] NOT NULL,
    [AllowedRequests] [smallint] NOT NULL,
    [ResetDateUtc] [datetime2](0) NOT NULL,

    CONSTRAINT [PK_RateLimit] 
        PRIMARY KEY CLUSTERED ([UserId] ASC, [EndPointId] ASC)
) ON [PRIMARY]

在这个表上执行CRUD操作的过程是多线程的,因此需要仔细考虑这个表,它作为速率限制检查的结果(即我们超过了我们的速率限制,我们可以制作另一个请求,等等。)

我正在尝试引入SQL锁,以使应用程序能够可靠地INSERT,UPDATE和SELECT值,而不会从其下面更改值。除了正常的复杂性之外,最大的痛点是UserId + EndPointId的RateLimit记录可能不存在 - 并且需要创建。

enter image description here

我一直在研究SQL锁,但问题是如果速率限制记录尚不存在(即首次运行),那么可能没有要锁定的行

我考虑过创建一个专门用于控制锁流的临时表 - 但我不确定这是如何工作的。

在最远的极端,我可以将SQL语句包装在SERIALIZABLE事务中(或者某种程度上的事情),但锁定整个表会产生严重的性能影响 - 我只关心用户ID + endpointid primary键,并确保一次只能由一个进程读取+更新/插入特定行。

我该如何处理这种情况?

版本: SQL Server 2016

注意: READ_COMMITTED_SNAPSHOT已启用

0 个答案:

没有答案