Ручная блокировка вручную в SQL Server? - PullRequest
0 голосов
/ 26 июля 2011

Я новичок в SQL Server, но хорошо разбираюсь в простых вещах, таких как выбор / обновление / удаление и другие транзакции.Я сталкиваюсь со сценарием блокировки в моем приложении.Я понял сценарий, поскольку многие потоки параллельны, пытаясь запустить набор операций обновления.Это не одно обновление, а набор операций обновления.

Я понял, что этого нельзя избежать в моем приложении, так как многие люди хотят сделать обновление одновременно.Поэтому я хочу иметь систему ручной блокировки.Сначала поток 1 должен проверить, доступна ли ручная блокировка, а затем начать транзакцию.Имеется в виду, что если второй поток запрашивает блокировку, он должен быть занят и, следовательно, второй поток должен ждать.Как только первый завершен, второй должен получить блокировку и начать транзакцию.

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

Ответы [ 3 ]

2 голосов
/ 26 июля 2011

Скорее всего, вы все равно окажетесь в том же сценарии. Наличие мертвого замка, основанного вокруг ваших сделанных на заказ замков. SQL Server внутренне реализует очень надежный механизм блокировки. Вы должны использовать это.

Проблема, с которой вы сталкиваетесь, заключается в том, что ресурсы (таблицы, индексы и т. Д.) Доступны (или изменены) в конфликтном порядке различными транзакциями / потоками.

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

  1. Поток 1 создает блокировку для записи клиента
  2. Поток 2 создает блокировку записи заказа
  3. Поток 1 пытается создать блокировку для записи заказа (но не может продолжить работу из-за шага 2)
  4. Поток 2 пытается создать блокировку для записи клиента (но не может продолжить работу из-за шага 3)

Вуаля ... тупик

Решение состоит в том, чтобы изменить методы доступа к ресурсам, чтобы к записям всегда обращались в одном и том же порядке, и проблема исчезнет.

  1. Поток 1 создает блокировку для записи клиента
  2. Поток 2 пытается создать блокировку для записи клиента (но не может продолжить работу из-за шага 1)
  3. Поток 1 создает блокировку записи заказа
  4. Поток 1 завершает транзакцию и разблокирует записи о заказах и клиентах
  5. Поток 2 создает блокировку для записи клиента
  6. Поток 2 создает блокировку записи заказа

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

2 голосов
/ 26 июля 2011

Вы, вероятно, имеете в виду "семафор". То есть что-то, чтобы сериализовать выполнение DML только одному процессу, может выполняться одновременно.

Это собственный SQL Server, использующий sp_getapplock

Вы можете настроить 2-й процесс на ожидание или сбой при вызове sp_getapplock, а также он может автоматически отменяться в режиме «транзакции».

0 голосов
/ 26 июля 2011

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

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

Microsoft имеет документацию, которую можно найти здесь. http://support.microsoft.com/kb/832524

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

...