只想在我遇到的问题上获得一些观点/可能的线索。
我有一个存储过程,用于更新/删除数据库中表的记录,它删除的表是一个实时表,临时保存数据,还更新存档表中的记录。 (报告等...)它正常工作,没有问题。
然而,最近我曾在Windows服务上监视我们的系统(24/7运行),它使用HTTP调用来启动一个程序,一旦这个程序完成它,然后运行提到的存储过程来删除冗余数据。基本上,该服务只是快速运行程序,以确保其正常运行。
我最近注意到数据并不总是被删除。查看日志我发现没有报告错误。甚至看到数据库中的记录已经正确更新。但是没有被删除。
不幸的是,这会对监控服务产生影响,因为这会不断运行,并发出警报,因为数据无法在实时表中复制,因此需要删除数据。
目前我已经制定了清除任何旧数据的程序。 (3小时)。
结果具有值 - 已拒绝。
以下是存储过程:
DECLARE @PostponeUntil DATETIME;
DECLARE @Attempts INT;
DECLARE @InitialTarget VARCHAR(8);
DECLARE @MaxAttempts INT;
DECLARE @APIDate DATETIME;
--UPDATE tCallbacks SET Result = @Result WHERE CallbackID = @CallbackID AND UPPER(Result) = 'PENDING';
UPDATE tCallbacks SET Result = @Result WHERE ID = (SELECT TOP 1 ID FROM tCallbacks WHERE CallbackID = @CallbackID ORDER BY ID DESC)
SELECT @InitialTarget = C.InitialTarget, @Attempts = LCB.Attempts, @MaxAttempts = C.CallAttempts
FROM tConfigurations C WITH (NOLOCK)
LEFT JOIN tLiveCallbacks LCB ON LCB.ID = @CallbackID
WHERE C.ID = LCB.ConfigurationID;
IF ((UPPER(@Result) <> 'SUCCESSFUL') AND (UPPER(@Result) <> 'MAXATTEMPTS') AND (UPPER(@Result) <> 'DESTBAR') AND (UPPER(@Result) <> 'REJECTED')) BEGIN
--INSERT A NEW RECORD FOR RTNR/BUSY/UNSUCCESSFUL/REJECT
--Create Callback Archive Record
SELECT @APIDate = CallbackRequestDate FROM tCallbacks WHERE Attempts = 0 AND CallbackID = @CallbackID;
BEGIN TRANSACTION
INSERT INTO tCallbacks (CallbackID, ConfigurationID, InitialTarget, Agent, AgentPresentedCLI, Callee, CalleePresentedCLI, CallbackRequestDate, Attempts, Result, CBRType, ExternalID, ASR, SessionID)
SELECT ID, ConfigurationID, @InitialTarget, Agent, AgentPresentedCLI, Callee, CalleePresentedCLI, @APIDate, @Attempts + 1, 'PENDING', CBRType, ExternalID, ASR, SessionID
FROM tLiveCallbacks
WHERE ID = @CallbackID;
UPDATE LCB
SET PostponeUntil = DATEADD(second, C.CallRetryPeriod, GETDATE()),
Pending = 0,
Attempts = @Attempts + 1
FROM tLiveCallbacks LCB
LEFT JOIN tConfigurations C ON C.ID = LCB.ConfigurationID
WHERE LCB.ID = @CallbackID;
COMMIT TRANSACTION
END
ELSE BEGIN
-- Update the Callbacks archive, when Successful or Max Attempts or DestBar.
IF EXISTS (SELECT ID FROM tLiveCallbacks WHERE ID = @CallbackID) BEGIN
BEGIN TRANSACTION
UPDATE tCallbacks
SET Attempts = @Attempts
WHERE ID IN (SELECT TOP (1) ID
FROM tCallbacks
WHERE CallbackID = @CallbackID
ORDER BY Attempts DESC);
-- The live callback should no longer be active now. As its either been answered or reach the max attempts.
DELETE FROM tLiveCallbacks WHERE ID = @CallbackID;
COMMIT
END
END
答案 0 :(得分:2)
您需要修复您的交易处理。发生的事情是一个语句失败但由于您没有try-catch块,所有更改都不会仅回滚失败的语句。
如果没有try catch块和错误回滚,你应该永远不会有一个begin tran。我个人也喜欢这样的东西将错误和相关数据放入表变量(不会回滚),然后在回滚后插入异常表。这样,数据保持完整性,您可以查找问题所在。