Как заставить блокировку SELECT на SQL-сервере?

Я вижу так много информации об исключении блоков. Моя ситуация в том, что я ХОЧУ блокировать.

У нас есть эта таблица, с которой два отдельных процесса будут обмениваться друг с другом. Процессы будут выполняться в произвольные моменты времени и будут использовать эту таблицу управления, чтобы понять, занят ли другой процесс. Оба процесса не могут быть заняты одновременно, следовательно, контрольная таблица.

Каждое задание при запуске проверяет контрольную таблицу … и на основе этих данных будет решаться, будет ли это нормально работать, и если ОК, обновит запись таблицы управления.

Проблема в том, что если оба процесса работают в один и тот же момент, неясно, что они не будут выполнять следующие нежелательные действия (в этом точном порядке):

  1. Proc A читает контрольную таблицу (таблица говорит, что нужно идти)
  2. Proc B считывает контрольный стол (таблица говорит, что нужно идти)
  3. Proc Контрольная таблица обновлений (таблица теперь говорит, что «Proc A занят»)
  4. Proc B обновляет контрольную таблицу (таблица теперь говорит, что «Proc B занят»)

<- В этом сценарии оба процесса считают, что они успешно обновили контрольную таблицу и начнут свой основной поток (что НЕ то, что мы хотим)

Я хочу здесь, чтобы Proc B был BLOCKED из SELECTING (а не только обновления) из таблицы управления. Таким образом, если / когда окончательный запрос Proc B в конечном итоге будет работать, он увидит обновленное значение «занято», а не значение, существовавшее до изменения в Proc A.

Я использую SQL Server 2008 R2. Я проверил изоляцию SERIALIZABLE, но, похоже, он недостаточно силен.

Для чего это стоит, мы пытаемся выполнить это с помощью JDBC … используя conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);

Мы понимаем, что это самый высокий уровень изоляции, но я все еще могу запускать выборки весь день из другого окна.

Я на 100% уверен, что это нигде не похоже на уникальную проблему … есть ли у кого-нибудь предложения для этой работы?

Ваш подход может работать, но есть несколько вещей, которые следует учитывать:

  1. Вам нужно открыть транзакцию в самом начале (до первого чтения), и вы должны выполнить ее только после того, как закончите свою работу.

  2. Если оба A и B попытаются прочитать / изменить одну и ту же запись , это будет работать из коробки, даже с уровнем изоляции транзакции по умолчанию (READ COMMITTED). В противном случае вам нужно указать SQL Server заблокировать всю таблицу (используя подсказку TABLOCK ).

  3. На самом деле, вам не нужны чтения вообще!

Вот как это будет работать:

  P1 P2 --------------------------------- BEGIN TRANS BEGIN TRANS WRITE (success) WRITE (blocked) do work | . | . | COMMIT -> block released, WRITE finishes do work . . COMMIT 

PS: Обратите внимание, что SQL-сервер поддерживает блокировки приложений . Таким образом, если вы просто хотите синхронизировать два процесса, вам не нужно «злоупотреблять» таблицей:

  • Внедрение блокировок приложений в SQL Server (шаблон распределенной блокировки)

PPS: Для полноты позвольте мне также ответить на вопрос в заголовке ( «Как заставить блокировку SELECT на SQL-сервере?» ): Для этого вы можете использовать комбинацию HOLDLOCK и XLOCK таблицы XLOCK (или TABLOCKX , если вы хотите полностью заблокировать всю таблицу).

Если вам нужно прочитать (потому что вы хотите обработать), я бы сделал следующее:

 Set transaction isolation level serializable begin transaction select from tablea update tablea commit 
  • автоинкремент буквенно-цифрового идентификатора для таблицы на основе уникального идентификатора другой таблицы
  • Заменить значения для столбца, если другой столбец верен
  • Найти значение таблицы между диапазоном столбца в sql
  • DELETE FROM table становится тяжелым, так как количество записей в файлах таблицы увеличивается
  • Используйте определенную базу данных и таблицу в MSSQL (Visual Studio)
  • Печать переменных и сообщений в T-Sql в SQL Server
  • Запрос той же таблицы для списка баз данных в MS SQL Server
  • Инструменты разработчика для прямого доступа к базам данных
  • Создание SSIS-пакета Hresult: 0x80004005 Описание: ошибка «Истекло время ожидания входа»
  • #SQL - Сравнить различные таблицы и создать новую таблицу
  • T-SQL ORDER BY в соответствии с условием
  • Interesting Posts

    Как понять, какая таблица / строка участвует в LCK_M_U RID: 7: 1: 11826: 0?

    Поддержка как MS-SQL, так и Oracle

    Как присоединиться к результату двух операторов sql в одной таблице и разных столбцах

    Поиск слов в индексе SQL Server

    Показать 3 результата от каждого элемента в группе по

    Получение имени базы данных из базы данных SQL Server Express в Visual Studio

    Преобразуйте таблицы с столбцами «id, attribute, value» в «id, attribute1, attribute2, …»

    SQL Фильтрация столбца захвата даты и его захват за 10 дней до начала записи

    Количество дней в диапазоне дат с набором исключений, которые могут перекрываться

    SQL-запрос для обновления столбцов таблицы, где входные параметры не являются нулевыми?

    Выберите 2 разных значения из 2-х таблиц

    Запрос, чтобы получить цену от одной записи и дату от другого

    Ошибка Sql: строка подключения не содержит требуемого атрибута providerName

    Как выбрать первую строку соответствия из инструкции CASE в SQL Server

    SQL Server: неправильный синтаксис

    Давайте будем гением компьютера.