我有一个链接缩短服务,数据库中存在大量密钥,这些密钥在一定时间后过期,然后可以重新分配。
我最近开始得到很多冲突,所以做了一些修改来创建一个锁在桌面上,不幸的是我只是在同一时间创建了两个引线(至1/000秒)
想知道如果有人对如何解决这个问题有任何想法,我无法想象它会在几周内发生,但随着业务的增长,这将使问题更加激烈。
该列不是唯一的,因为我们保留了系统中创建的每个URL的记录,因此url键在表中多次使用。
代码如下所示:
BEGIN TRAN GetNextUrlToAssign
DECLARE @res AS INT
EXEC @res = sp_getapplock
@Resource = 'GetKeyForURL',
@LockMode = 'Exclusive',
@LockOwner = 'Transaction',
@LockTimeout = 20000, -- time in milliseconds.
@DbPrincipal = 'public'
IF @res < 0
BEGIN
RAISERROR ( 'psp_GetKeyForURL: Unable to acquire Lock', 16, 1 )
ROLLBACK TRAN GetNextUrlToAssign
--RETURN -1
END
SELECT TOP 1 @OldIMID = IMID, @URLKey = URLKey
FROM IM A WITH (INDEX(IX_DateAvailable) )
WHERE DateAvailable < CURRENT_TIMESTAMP
AND DateReallocated IS NULL
UPDATE IM
SET DateReallocated = GETDATE()
WHERE IMID = @OldIMID
EXEC @res = sp_releaseapplock @Resource = 'GetKeyForURL';
COMMIT TRAN GetNextUrlToAssign
答案 0 :(得分:0)
过了一会儿,但这个问题让人头疼,开始在我的数据库上创建锁定。
在与另一位开发人员交谈后,他告诉我MsSql不应该真正用作队列。有用于创建队列的特定软件:
http://msdn.microsoft.com/en-us/library/ms711472(v=vs.85).aspx
没有任何经验,但从简短的阅读中看,它们似乎是使用的技术。
但是我仍然需要修复我的问题,慢查询和锁定数据库,一些查询正在建立,最慢的需要30秒才能完成。
我的解决方案是构建第二个表,我的主表有1000行,存储过程确保表总是每五分钟完全填充一次。
聪明的部分来自使用事务,锁定提示UPDLOCK和READPAST。
UPDLOCK为您提供了对该行的锁定,READPAST允许下一个请求读取后续行,如下面的示例所示。您需要在正在使用的列上有索引。
这个解决方案给了我一个相当高效的查询,我在开发的两秒钟内测试了三个客户端上的大约150个链接。
BEGIN TRAN GetNextUrlToAssign
SELECT TOP 1 @OldID = q.ID, @URLKey = q.URLKey
FROM Queue q WITH (UPDLOCK, READPAST)
WHERE q.Deleted = 0
AND q.DateReallocated IS NULL
UPDATE Queue
SET Deleted = 1
WHERE ID = @OldID
COMMIT TRAN GetNextUrlToAssign
如需进一步阅读,请尝试以下文章: