Кто-либо может помочь мне для мертвой блокировки в SQL Server 2005?
Для простого теста у меня есть таблица "Book", которая имеет первичный ключ (идентификатор) и имя столбца. Индекс по умолчанию этого первичного ключа не кластеризируется.
Мертвая блокировка происходит когда две сессии, выполненные в то же время. Монитор действия показывает первую сессию "//, шаг 1" блокирует строку (избавленная блокировка) с X блокировками. Вторая сессия сохраняет строку U блокировкой и ключом U блокировка. Шоу изображения мертвой блокировки "//step2" первой сессии требуют ключа U блокировка.
Если индекс кластеризируется, в этом случае нет никакой мертвой блокировки. "//шаг 1" сохранит блокировку строки и блокировку ключа в то же время, таким образом, не будет никакой проблемы. Я могу понять, что блокировка строки также заблокирует индекс, так как вершина кластерного индекса является данными строки.
Но, почему некластеризованный индекс таким образом? Если вторая сессия удерживает клавишу U блокировка, почему "шаг 1" первой сессии не содержит эту блокировку, так как они - то же оператор обновления.
--// first session
BEGIN TRAN
update Book set name = name where id = 1 //step 1
WaitFor Delay '00:00:20'
update Book set name = 'trans' where id = 1 //step2
COMMIT
--// second session
BEGIN TRAN
--// this statement will keep both RID(U lock) and KEY(U lock) if first session did not use HOLDLOCK
update Book set name = name where id = 1
COMMIT
Этот вопрос уже заставил меня поцарапать голову. Для меня это вопрос семантики. Мне кажется более естественным делать
<page size="a4">
, чем
<page>
<size>a4</size>
</page>
-121--3095737- W3C - События объектной модели документа - но как всегда... некоторые браузеры не поддерживают все.
-121--3397791- Здесь релевантным фактором является использование столбца в предложении , где
имеет некластеризованный индекс. Когда SQL Server обрабатывает обновление, это происходит примерно так:
После завершения инструкции (при изоляции по умолчанию READ COMMITTED
) U-блокировки освобождаются, но X-блокировки удерживаются до тех пор, пока
В некластеризованной ситуации с индексами SQL Server выполняет поиск индекса по идентификатору и использует его для поиска фактической строки. Блокировка выполняется следующим образом:
Однако, когда индекс является кластеризованным индексом, нет отдельного шага для преобразования ключа индекса в строку - значение кластеризованного индекса является идентификатором строки. Следовательно, блокировка заканчивается следующим образом:
Как всегда, имейте в виду, что, хотя это может быть план запроса, используемый в этом случае, оптимизатор может делать вещи по-другому. Например, он может выбрать сканирование таблицы или снять более крупнозернистые блокировки. В этих случаях взаимоблокировки может не произойти.
Эта ссылка имеет много полезных предложений: неблокирует SQL Server между выбором / обновлением или несколькими выборами .
Вот некоторые очки, которые нужно рассмотреть, что может помочь людям ответить на ваш вопрос:
Я думаю, что ответ С. Лотта является гораздо лучшим способом реализации государственной машины, но если вы все еще хотите продолжить свой подход, использование (состояние, событие)
в качестве ключа для вашего dict
лучше. Изменение кода:
class HandlerFsm(object):
_fsm = {
("state_a","event"): "next_state",
#...
}
-121--1117095- Почти идентичен @ Thomas, но другой метод -
При условии, что dt1 больше dt2
if(dt1.Sutract(dt2).TotalMinutes < 5)
{
// do
}
Основное отличие состоит в том, что он использует пространство памяти dt1 для выполнения вычитания.
Edit: использование коррекции TotalMinutes. Метод substract все еще присутствует в объекте datetime, поэтому я оставлю его здесь.
-121--2786173-Ваше первое обновление ничего не изменяет:
update Book set name = name where id = 1
Эта команда фактически изменяет ваш столбец, после чего на строке будет удерживаться исключительная блокировка.