SQL Server中的手动信号量

时间:2015-01-30 15:45:06

标签: sql-server

我试图将时间限制的信号量放入sql数据库。锁应该对数据表的写访问提供互斥,但仅涉及某个FK值(电子邮件),这就是我不能使用表锁或类似的原因。并且由于我不相信sql连接要保持或锁定在所有情况下都被释放(当然我们尝试,但更安全而不是遗憾),如果没有续订或释放,锁定将在3分钟后超时之间。

到目前为止,我有以下SQL语句:

UPDATE users SET lockTime = GETDATE() OUTPUT DELETED.LockTime WHERE email = @mail

问题:如果用户在表中,这将始终更新lockTime并返回旧的lockTime。因此,如果孤立锁有效并且查询以2分钟为间隔运行,则永远不会释放锁。 (为了测试它周围的所有逻辑,这没关系,但不适用于生产。)

只有在比3分钟更早的时候才应更新lockTime。所以我试过了:

UPDATE users SET lockTime = GETDATE() OUTPUT DELETED.LockTime 
WHERE email = @mail AND DATEADD(lockTime,'3 minutes')<GETDATE()

但是这甚至不能用于测试代码,因为我无法区分“电子邮件不在DB中”和“锁定小于3分钟”的情况。

那么,我在哪里想错了?

1 个答案:

答案 0 :(得分:3)

这会做得更好:

UPDATE users
SET lockTime = 
CASE WHEN DATEADD(lockTime,'3 minutes')<GETDATE() THEN GETDATE()
ELSE lockTime END
OUTPUT DELETED.LockTime
WHERE email = @mail

我们使用CASE来决定是否实际更新lockTime