Могут ли внешние ключи вызвать взаимные блокировки и помешать READ COMMITTED SNAPSHOT?

19

Это дополнительный вопрос от: /programming/7684477/is-it-possible-to-set-transaction-isolation-level-snapshot-automatics

У меня все еще возникают ситуации блокировки / тайм-аута в приложении ASP.NET при одновременном запуске больших отчетов READ_COMMITTED_SNAPSHOT ON.

Итак, у меня есть два вопроса:

  1. Как я могу проверить, работает ли моментальный снимок уровня изоляции транзакции как ожидалось / вообще?
  2. Я предполагаю, что внешние ключи (в таблицах веб-приложения к таблицам отчетов) отвечают за взаимоблокировки. Я нашел эту интересную статью :

Примечание. SQL Server получает общие блокировки при проверке внешних ключей, даже если в транзакции используется моментальный снимок с фиксацией чтения (подтверждение с фиксацией строк) или уровень изоляции моментального снимка. Помните об этом при изучении графиков взаимоблокировок из транзакций, когда используются эти уровни изоляции транзакций. Если вы видите общие блокировки, проверьте, приняты ли блокировки для объекта, на который ссылается внешний ключ.

Как я могу проверить, действительно ли FK отвечает за ситуации тупиковой ситуации / тайм-аута, означает ли это, что я могу удалить эти внешние ключи, чтобы предотвратить взаимные блокировки (что было бы приемлемым усилием)?

Примечание : я читаю только из таблиц, которые вызывают тупики.

Любые мысли на эту тему с благодарностью.


Редактировать Вот тупиковый график . Может быть, кто-нибудь может помочь мне понять, что вызывает тупик. Похоже, что это происходило без запуска каких-либо отчетов, вызванных только веб-приложением, когда две транзакции хотят записать одну и ту же таблицу (одно обновление и одна вставка, вставка как хранимая процедура). Почему он блокирует страницы и как включить только блокировки строк? Insert-SP использует уже TRANSACTION ISOLATION LEVEL REPEATABLE READ.

У меня есть сильное подозрение, что два триггера (одно обновление и одна вставка) отвечают за взаимоблокировки. Вот триггер вставки:

CREATE TRIGGER [dbo].[CreateRMAFiDates] 
   ON  [dbo].[RMA] 
   AFTER INSERT
AS 
BEGIN
    SET NOCOUNT ON;

    UPDATE RMA 
    SET [fiCreationDate]=(SELECT idDate FROM tdefDate 
        WHERE CONVERT(VARCHAR, INSERTED.Creation_Date, 112) = tdefDate.Text),
        [fiPopDate]=(SELECT idDate FROM tdefDate 
        WHERE CONVERT(VARCHAR, INSERTED.POP_Date, 112) = tdefDate.Text),
        [fiManufactureDate]=(SELECT idDate FROM tdefDate 
        WHERE CONVERT(VARCHAR, INSERTED.Manufacture_Date, 112) = tdefDate.Text)
    FROM INSERTED;
END

Таким образом, этот триггер обновляет таблицу RMA, что вызывает срабатывание триггера обновления (что делает подобное). График взаимоблокировки подтверждает мое предположение? Я думаю, что удаляю эти триггеры и создаю SP, который запускается раз в день, что будет вполне достаточно, потому что эти столбцы предназначены только для SSAS-Cube (Molap).

Редактировать : Кстати, тупика больше не было, так как я удалил эти триггеры :)

Тим Шмельтер
источник

Ответы:

16

Если команда SQLCAT говорит, что проверка FK выполняется с использованием изолированной фиксации чтения, то они должны знать, о чем они говорят. Акцент на валидации . Реальный вопрос заключается в том, почему отчет вызывает проверку FK ? Проверка происходит при записи , и отчеты должны быть прочитаны . Либо ваши отчеты вызывают записи, и в этом случае уровни изоляции моментальных снимков ничего не помогут, либо причина тупика другая.

Единственный способ добиться прогресса - захватить график тупиковой ситуации.

Что касается другого вопроса, как вы можете проверить, работаете ли вы под изоляцией моментального снимка: посмотрите sys.dm_tran_active_snapshot_database_transactions.

Ремус Русану
источник
2

Проверка внешнего ключа имеет происходить под (замок) читать совершенные на правильность. См. Раздел « Снимок изоляции: угроза целостности»? Уго Корнелис для деталей.

График взаимоблокировки показывает два одновременных выполнения RM2.dbo.RMAвызова взаимоблокировки. В ваших триггерах отсутствует условие соединения между RMAи inserted.

Вполне вероятно, что это недосмотр, и ваш триггер случайно обновляет все строки, RMAпоэтому очень вероятно возникновение взаимоблокировок при одновременном выполнении нескольких триггеров.

user126897
источник