Самый чистый способ, как сказал г-н Потато Хэд, состоит в том, чтобы просто использовать предложение WHERE, чтобы воздействовать только на строки, где lock_status = 0. Поскольку это один оператор SQL, он гарантированно будет атомарным. Затем вы можете увидеть, были ли затронуты какие-либо строки (например, с помощью @@ rowcount), и соответственно отреагировать, либо повторив попытку бесконечно, либо показав сообщение об ошибке и т. Д.
Проблема с проверкой и обновлением в два этапа заключается в том, что если вы не заключите их в явную транзакцию (например, «BEGIN TRANSACTION ... COMMIT TRANSACTION»), они не гарантированно будут атомарными, поэтому теоретически вы можете получить более одного процесса, который думает, что блокировка отключена и продолжается. Я говорю «теоретически», потому что с той скоростью, с которой выполняются эти операторы, невероятно маловероятно, что это когда-либо произойдет, если у вас не будет чрезвычайно параллельной среды с сотней (тысяч?) Пользователей, одновременно стучащих в эту штуку. Вот почему ошибки, подобные этой, часто остаются незамеченными, но позже возникают неожиданные необъяснимые ошибки.
Чтобы узнать больше об этой проблеме, вы можете прочитать книгу о параллельном программировании, такую как эта: Параллельное программирование Грегори Эндрюса .