我有一个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
记录可能不存在 - 并且需要创建。
我一直在研究SQL锁,但问题是如果速率限制记录尚不存在(即首次运行),那么可能没有要锁定的行。
我考虑过创建一个专门用于控制锁流的临时表 - 但我不确定这是如何工作的。
在最远的极端,我可以将SQL语句包装在SERIALIZABLE事务中(或者某种程度上的事情),但锁定整个表会产生严重的性能影响 - 我只关心用户ID + endpointid primary键,并确保一次只能由一个进程读取+更新/插入特定行。
我该如何处理这种情况?
版本: SQL Server 2016
注意: READ_COMMITTED_SNAPSHOT已启用