Quantcast
Channel: Transact-SQL forum
Viewing all articles
Browse latest Browse all 23857

Record locking issues and error handling framework

$
0
0

Hi all,

I have a number of stored procedures that are called in parallel by SSIS to rebuild tables during an overnight process in a data warehouse. I am using a common table (named PL_ProcessLog) to log when each sproc starts and ends. I am getting locks occuring on PL_ProcessLog as several sprocs try and create a row in this table at the same time. The code to insert into this table is in a sproc of its own, which is wrapped in a tight transaction each time it is called.

The sproc that inserts a row in the log table is:

USE lib
GO
IF OBJECT_ID(N'dbo.PL_LogProcessStart', N'P') IS NOT NULL DROP PROCEDURE PL_LogProcessStart
GO
CREATE PROCEDURE dbo.PL_LogProcessStart
	@ComponentName NVARCHAR(100),
	@ProcessName NVARCHAR(100),
	@StepName NVARCHAR(100),
	@ID UNIQUEIDENTIFIER OUTPUT
AS
	SET @ID = NEWID()
	--SET @StepName = @StepName + ' (SPID:' + CAST(@@SPID AS VARCHAR(4)) + ')'
	INSERT	PL_ProcessLog WITH (ROWLOCK)
			(Identifier,
			ComponentName,
			ProcessName,
			StepName,
			StartDate)
	VALUES	(@ID,
			@ComponentName,
			@ProcessName,
			@StepName,
			GETDATE())
	OPTION (MAXDOP 1)
GO

The calling code all looks as below, in this instance I am showing one called PMI_PopulateNameHistory, but they all take the same framework:

USE DW
GO
IF OBJECT_ID('dbo.PMI_PopulateNameHistory', 'P') IS NOT NULL DROP PROCEDURE dbo.PMI_PopulateNameHistory
GO
CREATE PROCEDURE dbo.PMI_PopulateNameHistory
/*
	Clears down and repopulates the name history table.
	Depends on:
		camis.pmi.pmi_othernames
		DW..PMI_Patient
*/
AS
	DECLARE @ID UNIQUEIDENTIFIER
	DECLARE @ID2 UNIQUEIDENTIFIER
	DECLARE @Message NVARCHAR(1000)
    DECLARE @ErrorSeverity INT
    DECLARE @ErrorState INT
	BEGIN TRY
		BEGIN TRANSACTION
		EXEC lib.dbo.PL_LogProcessStart 'PMI', 'PMI_PopulateNameHistory', 'PMI_PopulateNameHistory', @ID OUTPUT
		COMMIT TRANSACTION
		BEGIN TRANSACTION	
		/*
		code to rebuild a table
		*/
		COMMIT TRANSACTION
		BEGIN TRANSACTION
		EXEC lib.dbo.PL_LogProcessEnd @ID
		COMMIT TRANSACTION
	END TRY
	BEGIN CATCH
		IF @@TRANCOUNT > 0
			ROLLBACK TRANSACTION
		SET @Message = ERROR_MESSAGE()
        SET @ErrorSeverity = ERROR_SEVERITY()
        SET @ErrorState = ERROR_STATE()
		BEGIN TRANSACTION
		EXEC lib.dbo.PL_LogProcessFail @ID, @Message
		COMMIT TRANSACTION
		RAISERROR(@Message, @ErrorSeverity, @ErrorState)
	END CATCH
GO

The deadlock is occurring when two sprocs call PL_LogProcessStart at the same time. They deadlock each other. How can this be? They're both simply inserting one row, and the call is in a tight transaction. More widely, is there anything I could improve about the error handling/process logging above?

Any advice gratefully received. Thanks,

Mark


Mark Roworth


Mark Roworth


Viewing all articles
Browse latest Browse all 23857

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>