Как сделать параллельные вызовы хранимых процедур без тупиков? - PullRequest
0 голосов
/ 13 января 2019

У меня есть хранимая процедура, которая создает временную таблицу, вставляет в нее данные и выполняет некоторые манипуляции. После этого временная таблица удаляется. Я запускаю это в течение TRANSACTION. Но, несмотря на это, когда я запускал несколько экземпляров хранимой процедуры, она вызывала взаимоблокировку, и теперь хранимая процедура не отвечает. Есть ли способ это исправить? Хранимая процедура предназначена для создания общей бэкэнд-таблицы с текстом JSON.

CREATE OR ALTER PROCEDURE dbo.INSERT_PROCESSING
    @TableName NVARCHAR(128),
    @InsertStatement NVARCHAR(1000) 
AS 
BEGIN
    DECLARE
        @tableSK INTEGER,
        @attribute_list NVARCHAR(1000),
        @json_txt NVARCHAR(1000),
        @json_txt_final NVARCHAR(1000),
        @K_SK_SysKey NVARCHAR(1000),
        @tmp_create_stmt NVARCHAR(1000),
        @tmp_table_ddl1 NVARCHAR(1000),
        @tmp_table_ddl NVARCHAR(1000),
        @tmp_table_drop NVARCHAR(1000),
        @modified_insert_stmt NVARCHAR(1000)

    PRINT 'Values passed are' 
    PRINT '1. TableName: ' + @TableName
    PRINT '2. InsertStatement: ' + @InsertStatement

    --1. Derive TableSK
    SET  @tableSK = ( SELECT DISTINCT SK
           FROM [SS_PRODUCTS].[dbo].[METADATA_TABLE] WHERE RTRIM(LTRIM(TableName)) = LTRIM(RTRIM(SUBSTRING(@TableName, 2, 128)))); 

    --2. Parse out the atributes from the INSERT Statement
    SELECT @attribute_list = SUBSTRING(@InsertStatement, CHARINDEX('(', @InsertStatement) , LEN(@InsertStatement));
    PRINT 'Value of @attribute_list' + @attribute_list;
    SET @K_SK_SysKey = REPLACE(SUBSTRING(@attribute_list, 3 , CHARINDEX(',', @attribute_list)-3 ), '''', ''); 
    PRINT 'Value of @K_SK_SysKey ' + @K_SK_SysKey;
    SET @modified_insert_stmt = 'INSERT INTO [dbo].TMP_TABLE VALUES ' + @attribute_list;

    --3. Create a Tmp table with the metadata available

    SET @tmp_create_stmt = STUFF((SELECT ' ,' + UPPER(TColumnName) + ' ' + TColumnDataType
            FROM [dbo].[METADATA_TABLE] WHERE SK=@tableSK ORDER BY TColumnOrder
            FOR XML PATH('')  ) ,1,1,'') ;

    SET @tmp_table_ddl1 = RIGHT(@tmp_create_stmt, LEN(@tmp_create_stmt) -1);
    SET @tmp_table_ddl = 'CREATE TABLE [dbo].TMP_TABLE'   +  ' ( ' + @tmp_table_ddl1 + ' );'
    PRINT 'TABLE DDL is ' + @tmp_table_ddl;

    SET @tmp_table_drop = 'DROP TABLE IF EXISTS [dbo].TMP_TABLE' ;

    BEGIN TRANSACTION 
    -- Try catch to handle exceptions
    BEGIN TRY 
        EXEC (@tmp_table_drop);
        PRINT 'TMP Table dropped'
    END TRY 
    BEGIN CATCH
        PRINT 'Table drop was not successful' ;
        RETURN 10;
    END CATCH

    BEGIN TRY
     EXEC (@tmp_table_ddl);
     PRINT 'TMP Table re-created'

    END TRY
    BEGIN CATCH 
        PRINT 'Table creation was not successful' ;
        RETURN 20;  
    END CATCH

     BEGIN TRY
        EXEC (@modified_insert_stmt);
        PRINT ' Insert to TMP Table successful'

     END TRY
    BEGIN CATCH 
        PRINT 'Table insert was not successful';
        RETURN 30;  
    END CATCH

        --CREATE JSON
        SET @json_txt = (SELECT * FROM dbo.TMP_TABLE FOR JSON AUTO, INCLUDE_NULL_VALUES );
        SET @json_txt_final = REPLACE(REPLACE( @json_txt, '[', ''), ']', '');

        PRINT 'Final Json txt is ' + @json_txt_final; 

        -- Insert into the target table
        INSERT INTO [dbo].[CONSOLIDATED_TABLE] ( SK, K_SK_SysKey, ACCESS_DATA_JSON )
        VALUES (@tableSK, @K_SK_SysKey, @json_txt_final );

    IF @@TRANCOUNT > 0
    BEGIN
        COMMIT TRANSACTION
        PRINT '*** Data inserted successfully***'
    END
END;

1 Ответ

0 голосов
/ 13 января 2019

Если ваша временная таблица квалифицируется как таковая с помощью хеша '#'. Таблицы #temp должны содержаться в этом сеансе и не конфликтовать с другими сеансами:

CREATE TABLE [dbo].#TMP_TABLE
...