Linq-to-Sql Чтение-Тест-Запись как одна операция
Я имею Tasks
Таблица: Id (PK), TaskName, Status
Статус один из: В очереди, Занят, Завершено.
Я хочу использовать несколько потоков для обработки задач, и для этого я должен быть в состоянии выполнить одну операцию:
var task = db.Tasks.FirstOrDefault(t=>t.Status == (byte) TaskStatus.Queued);
task.Status = (byte) TaskStatus.Busy;
db.SubmitChanges();
Очевидно, что если операция не является атомарной, у меня могут возникнуть проблемы с параллелизмом. Каков (если таковой существует) предполагаемый способ сделать вышеизложенное с использованием Linq-to-Sql?
Я знаю, что могу сделать это с 1) Storproc или 2) db.ExecuteCommand("...")
или 3) урегулировать конфликт with try/catch
- но я хочу быть уверен, что лучшего способа нет.
Я знаю, что это очень простой вопрос, но я не смог найти однозначного ответа на этот вопрос.
1 ответ
Если вы хотите быть уверены, что это происходит атомарно в базе данных (независимо от того, какой поток или приложение его вызывает), вам, вероятно, следует сделать это в sproc и заблокировать на соответствующем уровне. Sproc должен извлечь и обновить запись, затем освободить и вернуть ее (Ack! Я не имею в виду TSQL return
Скажите, но вы знаете, я имею в виду select
это я верю!)
Таким образом, L2S просто вызывает sproc и возвращает задание для работы, уже установленное как Busy
, L2S не знает (и не заботится) о том, что / как было заблокировано, и поэтому не может усложнить ситуацию и увеличить шансы на взаимоблокировку.