我有一个存储过程从表中读取并做出决策,每分钟调用一次。我有一种情况,在24小时内,每小时有3到5个请求失败。我想也许桌子被锁定了什么?这是我的存储过程。我是否需要具有隔离级别等的交易?这个想法是在查询运行时没有任何东西可以读取或写入该表。它应该是原子的。
ALTER PROCEDURE [dbo].[requestUpdate]
AS
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRAN
DECLARE @StartDate datetime,
@EndDate datetime,
@Throttle bit,
@Expired bit
SELECT @Throttle = 0
SELECT @Expired = 0
SELECT TOP 1 @StartDate = uq.StartDate, @EndDate = uq.EndDate
FROM UpdateQueue uq WITH(TABLOCK,XLOCK)
ORDER BY ID DESC
-- PREVENT ANOTHER REQUEST IF THIS SP HAS BEEN
-- CALLED IN THE LAST FORTY SECONDS.
IF DATEADD(SECOND,-40,GETDATE()) < @StartDate
BEGIN
SELECT @Throttle = 1
END
-- CREATE ANOTHER REQUEST IF THE CURRENT ONE
-- HAS NOT COMPLETED IN THE LAST FIVE MINUTES.
IF @StartDate <= DATEADD(MINUTE,-5,GETDATE())
BEGIN
SELECT @Expired = 1
END
-- HAS THE CURRENT REQUEST EXPIRED?
IF @EndDate IS NULL AND @Expired = 1
BEGIN
INSERT INTO UpdateQueue (RequestID, StartDate) OUTPUT 'EXPIRED' AS Result, INSERTED.RequestID AS RequestID
VALUES (NEWID(), GETDATE())
END
-- HAS THE CURRENT REQUEST COMPLETED AND YOU ARE NOT THROTTLING
-- OR HAVE THERE NOT BEEN ANY REQUESTS YET?
ELSE IF (@EndDate IS NOT NULL AND @Throttle = 0) OR @StartDate IS NULL
BEGIN
INSERT INTO UpdateQueue (RequestID, StartDate) OUTPUT 'STARTED' AS Result, INSERTED.RequestID AS RequestID
VALUES (NEWID(), GETDATE())
END
-- Running
ELSE
BEGIN
SELECT 'RUNNING' AS Result, NULL AS RequestID
END
COMMIT
GO