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 не знает (и не заботится) о том, что / как было заблокировано, и поэтому не может усложнить ситуацию и увеличить шансы на взаимоблокировку.

Другие вопросы по тегам