Предотвращение взаимоблокировки между хранимой процедурой и выполнением представления

#sql #sql-server

#sql #sql-сервер

Вопрос:

У нас есть хранимая процедура, которая вставляет данные в 3 таблицы (определенные части хранятся в отдельных таблицах, управление версиями заказов на обновления):

 CREATE PROCEDURE [dbo].[SpecialOrders_Insert]
    @lastName nvarchar(100),
    @firstName nvarchar(100),
    @productId int,
    @blabla nvarchar(100),
    @special1 nvarchar(100),
    @special2 nvarchar(100),
    @special3 nvarchar(100),
    @changedBy int
AS
BEGIN
    SET NOCOUNT ON;
    SET XACT_ABORT ON;
    DECLARE @lastChangedDate datetime = GetDate();
    DECLARE @identity int

    BEGIN TRAN;

        -- Place Order-Head
        INSERT INTO dbo.Orders_H 
                    (LastName
                    , FirstName
                    , ProductId) 
        VALUES 
                    (@lastName,
                    @firstName,
                    @productId);

        SET @identity = SCOPE_IDENTITY();

        -- Place Order-Data (expect lot more data here)
        INSERT INTO dbo.Orders_D
                    (ParentId
                    , Blabla
                    , LastChangedDate
                    , LastChangedBy
                    , ValidFrom
                    , ValidTo)
        VALUES
                    (@identity
                    , @blabla
                    , @lastChangedDate
                    , @changedBy
                    , @lastChangedDate
                    , null);


        INSERT INTO dbo.SpecialOrders_D
                    (ParentId
                    , Special1
                    , Special2
                    , Special3
                    , LastChangedDate
                    , LastChangedBy
                    , ValidFrom
                    , ValidTo)
        VALUES
                    (@identity
                    , @special1
                    , @special2
                    , @special3
                    , @lastChangedDate
                    , @changedBy
                    , @lastChangedDate
                    , null);

    COMMIT TRAN;
END
  

И несколько представлений, которые всегда считывают текущие версии, такие как:
СОЗДАЙТЕ ПРЕДСТАВЛЕНИЕ [dbo].[Специальные порядки] КАК

     SELECT 
        -- Orders_H
        h.Id, h.LastName, h.FirstName, h.ProductId,

        -- Orders_D (expect lot more columns here)
        d.Blabla, 

        -- Specialorders (also here more data expected)
        s.Special1, s.Special2, s.Special3

    FROM Orders_H h
         left join Orders_D d ON h.Id = d.ParentId
         left join SpecialOrders_D s ON d.ParentId = s.ParentId

    WHERE d.ValidTo is null and s.ValidTo is null
  

В настоящее время мы сталкиваемся с взаимоблокировками, когда SP вставляет данные, а представление одновременно считывает данные. Sp удерживает эксклюзивную блокировку для Orders_H, в то время как представление удерживает общую блокировку для Orders_D.

Как я могу изменить представление, чтобы оно гарантировало чтение данных в правильном порядке: Orders_H, Orders_D, Specialorders?

Комментарии:

1. Можете ли вы поделиться .xdl? Я подозреваю, что это проблема с порядком доступа к индексу. Есть ли шанс, что вы сможете реализовать изоляцию моментальных снимков с фиксацией чтения?

2. почему бы не использовать с #NOWAIT

3. @AaronBertrand Я пытаюсь создать xdl с сокращенным сценарием, описанным выше. Реальный сценарий использует намного больше столбцов и некоторые fk и так далее. Я не уверен, что RCSI — хорошая идея. Нет ли значительных проблем с производительностью при работе с сильно обновленными таблицами?

4. @Hogan нет, это не вариант.

5. Ну, вам нравится устранять взаимоблокировки или настраивать базу данных tempdb? Почти все является компромиссом.