sp_getapplock
в значительной степени самый лучший и самый произвольный замок, который вы можете взять.Он функционирует больше, чем ключевое слово lock
в программировании ООО.По сути, вы называете ресурс, задаете ему область действия (процесс или транзакцию), а затем блокируете его.В значительной степени ничто не может обойти этот замок, поэтому он решил ваши гоночные условия.Это также, вероятно, безумное излишество за то, что вы пытаетесь сделать.
Первая идея кода / архитектуры, которая приходит на ум, - это реструктурировать эту таблицу.Я предполагаю, что у вас большие объемы обновлений, иначе вы не столкнетесь с этими нарушениями.Вы можете просто использовать блок try / catch и повторить попытку блока catch при нарушении PK.Неуклюжий, но может просто сделать трюк.
Далее, вы могли бы рассмотреть изменение структуры таблицы, которая получает этот поток обновлений в течение дня.Сделайте эту таблицу primary keyed
из столбца идентификаторов и ничего больше.Вставки будут молниеносными, поэтому любая блокировка будет незначительной.Затем вы можете переместить эти данные в пакетах в таблицу, лучше подходящую для пакетной обработки (в отличие от попыток пакетной обработки в реальном времени)
Существует также целый ряд настроек изоляции транзакций которые настраивают обычную систему блокировки SQL для поддержки различных вариантов (будь то на уровне пакета или внутри строки с помощью подсказок запроса. Я бы ознакомился с ними, но вы могли бы рассмотреть вопрос о последовательной изоляции. Различные параметры приведут в соответствие различные правила времени выполнения, чтобы соответствоватьваши потребности.
Также обязательно проверяйте свои транзакции. Возможно, вы хотите, чтобы заблокировал эту таблицу (и, возможно, во время какого-либо другого действия), но как только эта потребность исчезнет,так должен замок.