SQL Server, вставьте одну таблицу блокировок целых строк

У нас есть проблема с каким-то тупиком, и я разместил это question.

С некоторой помощью и большим количеством поисков я считаю, что я понял, что происходит. Чтобы решить тупиковые ситуации, не контролируя эскалацию блокировки, мне нужно понять, почему сервер sql блокирует всю таблицу при вставке одной строки.

Вот мой оператор insert (с переименованными переменными):

DECLARE 
    @Type1 INT = 11,
    @Type2 INT = NULL,
    @Value1 VARCHAR(20) = '0',
    @Value2 VARCHAR(20) = '0',
    @Value3 VARCHAR(20) = '0',
    @Value4 VARCHAR(20) = '0',
    @Date1 DATETIME = '2011-11-25',
    @Date2 DATETIME = '2011-11-25',
    @Value5 NVARCHAR(50) = '',
    @Value6 NVARCHAR(50) = '',
    @Type3 INT = NULL,
    @Value7 VARCHAR(20) = '4',
    @Type4 INT = 4,
    @Type5 INT = 15153,
    @Type6 INT = 3,
    @Type7 INT = 31,
    @Type8 INT = 5976,
    @Type9 INT = 5044,
    @Guid1 UNIQUEIDENTIFIER = 'a8293471-3hb4-442b-844f-44t92f17n67s',
    @Value8 VARCHAR(200) = '02jfgg55savolhffr1mkjf45',
    @value10 INT = 1,
    @Option2 BIT = 0,
    @Value9 VARCHAR(20) = null,
    @Option1 BIT = 0

insert into dbo.OurTable
(
    Type1
    ,Type2
    ,Value1
    ,Value2
    ,Value3
    ,Value4
    ,Date1
    ,Date2
    ,Value5
    ,Value6
    ,Type3
    ,Value7
    ,Type4
    ,Type5
    ,Type6
    ,Type7
    ,Type8
    ,Type9
    ,value10
    ,Col1
    ,Col2
    ,Col3
    ,Col4
    ,Value8
    ,Option2
    ,Value9
)
values
(
    CASE
        WHEN [dbo].[GetType](@Type1, null) = 6 AND @Option1 = 1 AND [dbo].[GetType](@Type4, 0) <> 1
        THEN 7
        ELSE [dbo].[GetType](@Type1, null)
    END
    ,[dbo].[GetType](@Type2, null)
    ,case when @Value1 = 'null' then null else CAST(@Value1 as numeric(18, 6)) end
    ,case when @Value2 = 'null' then null else CAST(@Value2 as numeric(18, 6)) end
    ,case when @Value3 = 'null' then null else CAST(@Value3 as numeric(18, 6)) end
    ,case when @Value4 = 'null' then null else CAST(@Value4 as numeric(18, 6)) end
    ,[dbo].[GetDate](@Date1, null)
    ,[dbo].[GetDate](@Date2, null)
    ,@Value5
    ,@Value6
    ,[dbo].[GetType](@Type3, null)
    ,case when @Value7 = 'null' then null else CAST(@Value7 as numeric(18, 6)) end
    ,[dbo].[GetType](@Type4, null)
    ,@Type6
    ,case when LOWER(@Type7) = 'null' then null else @Type7 end
    ,@Type5
    ,@Type9
    ,@Type8
    ,@value10
    ,GETDATE()
    ,GETDATE()
    ,[dbo].[GetGuid](@Guid1)
    ,[dbo].[GetGuid](@Guid1)
    ,@Value8
    ,@Option2
    ,case when @Value9 = 'null' then null else CAST(@Value9 as int) end
)

Если я запустил этот оператор в транзакции и затем запросил sys.dm_tran_locks перед тем, как совершить, я получаю 10233 строки, принадлежащие этому сеансу.

SELECT *
FROM sys.dm_tran_locks l
WHERE l.resource_type <> 'DATABASE' AND l.request_session_id = 65

65 - это идентификатор сеанса моего текущего окна при тестировании.

Также, если я смотрю на блокировку таблицы (что является причиной моего тупика), я вижу, что она помещает блокировку X в таблицу OurTable.

resource_type   resource_associated_entity_id   Name    resource_lock_partition request_mode    request_type    request_status
OBJECT  290100074   OurTable    0   X   LOCK    GRANT
OBJECT  290100074   OurTable    1   X   LOCK    GRANT
OBJECT  290100074   OurTable    2   X   LOCK    GRANT
OBJECT  290100074   OurTable    3   X   LOCK    GRANT
OBJECT  290100074   OurTable    4   X   LOCK    GRANT
OBJECT  290100074   OurTable    5   X   LOCK    GRANT
OBJECT  290100074   OurTable    6   X   LOCK    GRANT
OBJECT  290100074   OurTable    7   X   LOCK    GRANT
OBJECT  290100074   OurTable    8   X   LOCK    GRANT
OBJECT  290100074   OurTable    9   X   LOCK    GRANT
OBJECT  290100074   OurTable    10  X   LOCK    GRANT
OBJECT  290100074   OurTable    11  X   LOCK    GRANT
OBJECT  290100074   OurTable    12  X   LOCK    GRANT
OBJECT  290100074   OurTable    13  X   LOCK    GRANT
OBJECT  290100074   OurTable    14  X   LOCK    GRANT
OBJECT  290100074   OurTable    15  X   LOCK    GRANT

Я не знаю, было ли это сделано из-за блокировки эскалации или если он запрашивает исключительную блокировку в таблице от начала. В любом случае это вызывает у меня проблемы с тупиками.

Причина наличия 16 строк блокировки в одной таблице обусловлена ​​блокировкой разделения.

Мой вопрос: почему он не запрашивает эксклюзивный замок (IX) на столе? Вместо этого он запрашивает эксклюзивный замок. Как я могу это предотвратить? Я не получаю подсказок в настройке советника, я уже пробовал это.

ИЗМЕНИТЬ В OurTable есть триггер вставки, который обновляет поле в OurTable3. Это выглядит так:

UPDATE OurTable3 SET Date1 = NULL
    FROM OurTable3 as E 
        JOIN OurTable2 as C on E.Id = C.FKId
        JOIN OurTable as ETC on ETC.FKId = C.Id
            AND (ETC.Date2 IS NULL OR CAST(ETC.Date2 AS DATE) > E.Date1) 
            AND ETC.Type1 = 1

Как вы можете видеть, он не обновляет OurTable, а запрашивает OurTable, чтобы обновить правильную строку в OurTable3.

Ответ 1

Я нашел ответ. Небольшая ошибка от разработчика в нашей команде (я всегда виню всех остальных:-). Вероятно, я должен был знать ответ, потому что Мартин Смит указал в другом вопросе, что я должен проверить ALLOW_ROW_LOCKS и ALLOW_PAGE_LOCKS. Но в то время мы думали, что partitionid связан с индексом id, и я только проверил этот индекс.

Я создал новую таблицу с теми же данными. Эффект ушел, и у меня был только правильный фиксатор IX на новом столе. Затем я создал каждый индекс и протестировал между каждым созданием, пока я внезапно не получил эффект.

Я нашел этот индекс в нашей таблице:

CREATE NONCLUSTERED INDEX [IX_OurTable] ON [dbo].[OurTable] 
(
    [Col1] ASC,
    [Col2] ASC,
    [Col3] ASC,
    [Col4] ASC,
    [Col5] ASC
)
INCLUDE ( [Col6],
[Col7],
[Col8],
[Col9]) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = OFF, ALLOW_PAGE_LOCKS  = OFF, FILLFACTOR = 90) ON [PRIMARY]
GO

С ALLOW_ROW_LOCKS = OFF и ALLOW_PAGE_LOCKS = OFF это очевидно, что это повлияет на вкладку, а также на выбор.

Спасибо за ваши комментарии и большое спасибо Мартину, который действительно помог мне решить эти проблемы с тупиками.