2014-12-16 7 views
0

Здесь, я, с некоторыми вопросами.Вопросы о DeadLock

Я буду быстрым и простым.

Я работаю с SQL Server 2008, и я столкнулся с множеством вызовов о взаимоблокировках.

Пользователи говорят, что они работают, а затем они получают сообщение об ошибке

транзакции (идентификатор процесса) был заведен в тупик на ресурсах блокировки с другим процессом и был выбран в качестве тупиковой жертвы. Перезапустите транзакцию.

Поэтому я обращаюсь к разработчикам и предлагаю добавить WITH (NO LOCK) в запросах.

Это работает в 100% случаев.

Но, это право?

Есть ли что-то делать вместо этого, или это единственный способ избавиться от этих тупиков?

Thanks

ответ

1

ок. Таким образом, тупик - это два процесса, конкурирующих за одни и те же данные, но ожидающие завершения другого до его обновления (или освобождения блокировки). Одной из причин блокировки данных является предотвращение «грязного чтения». т. е. считывание устаревших данных, поскольку оно уже обновлено.

Таким образом, блокировка происходит по какой-либо причине, то есть там, чтобы защитить целостность ваших данных.Отключение его WITH (NO LOCK) должно выполняться только в том случае, если вы уверены, что ваша система не пострадает в результате. В противном случае вы начнете получать повреждение данных, т. Е. Плохие данные.

Я бы сказал, что использование WITH (NO LOCK) безопасно с процедурами, которые только сообщают, то есть выбирает без каких-либо последующих обновлений и не влияет на работу системы. Для процедур, которые выбирают, а затем обновляют не очень хорошо.

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

Итак, да, вы можете отказаться от блокировки, но будьте осторожны, это может оставить вам плохие данные. Лучше всего понять, что такое взаимоблокировка и определить, можно ли его улучшить. Если вы попытаетесь свести к минимуму блокировки путем снижения уровня изоляции, вам нужно будет использовать управление версиями строк, то есть каждое обновление проверяет, обновляет ли данные, которые он видел в последний раз, а если нет (то есть он был обновлен тем временем), он выдает ошибку ,

Here is a good MSDN article on how to reduce deadlocks

0

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

Держите транзакции недолго.

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

Получение блокировки записи спереди помогает несколько раз.

0

Это зависит от того, насколько вы заботитесь о согласованности чтения и насколько вы заботитесь о производительности.

  • С (NO LOCK) - Там нет блокировки чтения, но вы осуществляетесь несвежими, несогласованности данных
  • версии уровня Row - старая версия строки хранится «на стороне». Это также устраняет блокировку чтения на стоимости дополнительных накладных расходов для каждого DML, который вы делаете.

Подробнее здесь: http://technet.microsoft.com/en-us/library/ms188277(v=sql.105).aspx

0

NOLOCK и SET TRANSACTION ИЗОЛЯЦИЯ LEVEL READ UNCOMMITTED может быть полезным, но это не всегда правильный ответ. Это будет зависеть от ситуации. Самый большой риск, на мой взгляд, будет грязным. (Чтение данных, которые могут быть свернуты по какой-то причине.)

Вы можете прочитать здесь

http://sqlblog.com/blogs/tamarick_hill/archive/2013/05/06/pros-cons-of-using-read-uncommitted-and-nolock.aspx

Надежда, что помогает