Reputation: 1017
Just want to get some views/possible leads on an issue I have.
I have a stored procedure that updates/deletes a record from a table in my database, the table it deletes from is a live table, that temporary holds the data, and also updates records on a archive table. (for reporting etc..) it works normally and havent had an issues.
However recently I had worked on a windows service to monitor our system (running 24/7), which uses a HTTP call to initiate a program, and once this program has finished it then runs the mention stored procedure to delete out redundant data. Basically the service just runs the program quickly to make sure its functioning correctly.
I have noticed recently that the data isnt always being deleted. Looking through logs I see no errors being reported. And Even see the record in the database has been updated correctly. But just doesnt get deleted.
This unfortunately has a knock on effect with the monitoring service, as this continously runs, and sends out alerts because the data cant be duplicated in the live table, hence why it needs to delete out the data.
Currently I have in place a procedure to clear out any old data. (3 hours).
Result has the value - Rejected.
Below is the stored procedure:
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
Upvotes: 0
Views: 154
Reputation: 96552
You need to fix your transaction processing. What is happening is that one statement is failing but since you don't have a try-catch block all changes are not getting rolled back only the statement that failed.
You should never have a begin tran without a try catch block and a rollback on error. I personally also prefer in something like this to put the errors and associated data into a table variable (which will not rollback) and then insert then to an exception table after the rollback. This way the data retains integrity and you can look up what the problem was.
Upvotes: 2