我在SQL服务器数据库上有一个长时间运行的存储过程。我不希望它每十分钟运行一次以上。
一旦存储过程运行,我想将最新结果存储在LatestResult表中,并针对时间进行存储,并使所有调用该存储过程的结果在接下来的十分钟内返回该结果。
这部分相对简单,但我们发现,由于该过程检查LatestResult表并更新它,因此大型用户群体在同时调用该过程时会出现许多死锁。
在客户端/线程情况下,我会通过使用锁来解决这个问题,使第一个用户锁定函数,第二个用户遇到锁并等待结果,第一个用户完成他们的过程调用,更新LatestResult表,并解锁第二个用户,然后从LatestResult表中获取结果。
在SQL Server中是否有实现这种锁定的方法?
编辑:
以下是代码的基本外观,没有错误检查调用:
一旦存储过程运行,我想将最新结果存储在LatestResult表中,并针对时间进行存储,并使所有调用该存储过程的结果在接下来的十分钟内返回该结果。
这部分相对简单,但我们发现,由于该过程检查LatestResult表并更新它,因此大型用户群体在同时调用该过程时会出现许多死锁。
在客户端/线程情况下,我会通过使用锁来解决这个问题,使第一个用户锁定函数,第二个用户遇到锁并等待结果,第一个用户完成他们的过程调用,更新LatestResult表,并解锁第二个用户,然后从LatestResult表中获取结果。
在SQL Server中是否有实现这种锁定的方法?
编辑:
以下是代码的基本外观,没有错误检查调用:
DECLARE @LastChecked AS DATETIME
DECLARE @LastResult AS NUMERIC(18,2)
SELECT TOP 1 @LastChecked = LastRunTime, @LastResult = LastResult FROM LastResult
DECLARE @ReturnValue AS NUMERIC(18,2)
IF DATEDIFF(n, @LastChecked, GetDate()) >= 10 OR NOT @LastResult = 0
BEGIN
SELECT @ReturnValue = ABS(ISNULL(SUM(ISNULL(Amount,0)),0)) FROM Transactions WHERE ISNULL(DeletedFlag,0) = 0 GROUP BY GroupID ORDER BY ABS(ISNULL(SUM(ISNULL(Amount,0)),0))
UPDATE LastResult SET LastRunTime = GETDATE(), LastResult = @ReturnValue
SELECT @ReturnValue
END
ELSE
BEGIN
SELECT @LastResult
END
我不太确定分组的情况,但我找到了一个测试系统,执行时间大约为4秒。
我想有一些工作计划将其中一些记录存档,并将它们归纳为运行总数,这可能会有所帮助,因为在那个四秒表中有几百万行......
OR NOT @LastResult = 0
这个条件是正确的吗?这似乎会导致它在更新后立即进行更新,对吗? - Solomon Rutzky