Linq-to-sql read-test-test - запись как одна операция
-
09-10-2019 - |
Вопрос
у меня есть 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
- Но я хочу быть уверен, что нет лучшего способа.
Я знаю, что это очень простой вопрос, но я не смог найти определенный ответ на это.
Решение
Если вы хотите быть уверены, что это происходит атомным образом в базе данных (независимо от того, какая нить или приложение вызывает его), вы, вероятно, должны делать это в SPROC и заблокировать на соответствующем уровне. SPROC должен получить и обновлять запись, затем отпустить и вернуть его (ACK! Я не имею в виду TSQL return
заявление, но вы знаете, я имею в виду select
Это, я доверяю!)
Таким образом, L2 просто называет SPROC и возвращает задачу для работы, уже установленной как Busy
. Отказ L2 не знает (ни заботится) Что / то, как все было заблокировано - и поэтому не может усложнить дело и ввести больше шансов на тупики.