katit wrote:У меня немного по другому..
А именно - отдельная таблица хранит данные об упаковщике. Т.е. я и INSERT и UPDATE
Не понимаю смысл WITH (UPDLOCK) в вашем примере?
Или это как-то с транзакцией работает?
Думаю что моей главной проблемой было то что у меня 3 и 4 местами поменяны. Я переставил и думаю что проблема должна уйти
Я бы отдал предпочтение варианту Виктора. Он более DB way что ли.
Смысл следующий. Между проверкой или выборкой первого свободного заказа (select) и update проходит некоторое количество времени, или квантов процессора. За это время планировщик задач операционки может отдать управление другому потоку, который может выполнить те же действия проверки ресурса. Так как ни один поток еще не добрался до update, но оба уже выполнили select они оба решат что ресурс свободен и оба выполнят update. Чем это чревато понятно.
Дело в том что DB обеспечивает атомарность одного sql statement но не обеспечивает по умалчанию что последовательность statements будет атомарной. Транзакции именно для того и применяются что бы обеспечить атомарность последовательности операторов. Далее в целях улучшения производительности применяются различные уровни изоляции транзакций.
Гуглить: transaction isolation level.
Далее. Можно еще повысить производительность если вы четко знаете места потенциальных конфликтов (как в вашем случае). Можно ручками указать какие таблицы лочить и с каким уровнем изоляции. А остльные таблицы будут лочится с уровнем по умолчанием.
Смысл WITH (UPDLOCK) в том что прочитав значение - кандидат вы лочите эту строчку уже тем фактом что вы ее прочитали. И далее вы можете безопасно производить update зная что строка залочена и никто на нее уже не позарится. Эта ситуация является классикой DB и больше вариантов граболей вы найдете опять же в serialization isolation levels.
Никакой разрухи нет. (с) Проф. Преображенский.