Ответ ниже не является хорошим способом реализации пессимистического параллелизма. Вы не должны реализовывать это на уровне приложения. В РСУБД есть лучшие инструменты для этого.
Если вы блокируете строку в БД, это по определению pessimistic
.
Поскольку вы контролируете пессимистический параллелизм на уровне приложения, я не думаю, что имеет значение, какую область транзакции использует EF. EF автоматически запустит транзакцию на уровне базы данных, когда вы сохраните изменения.
Чтобы запретить нескольким потокам выполнять блокировку / разблокировку из вашего приложения, вы можете заблокировать раздел кода, который запрашивает и обновляет, например, так:
public static object _lock = new object();
public class MyClassThatManagesConcurrency
{
public void MyMethodThatManagesConcurrency()
{
lock(_lock)
{
// query for the data
// determine if item should be unlocked
// dbContext.SaveChanges();
}
}
}
С учетом вышеизложенного, никакие 2 потока не будут одновременно выполнять код внутри секции lock
. Однако я не уверен, почему это необходимо. Если все, что вы делаете, это читаете объект и разблокируете его по истечении времени, и 2 потока одновременно вводят метод, в любом случае, элемент становится разблокированным.
С другой стороны, если в вашей строке БД для этого объекта есть столбец timestamp
(не столбец datetime
, а столбец для строк контроля версий), и 2 потока одновременно вводят метод, второй будет получить исключение параллелизма. Но если у вас нет версий версий на уровне базы данных, я не думаю, что вам нужно делать какие-либо блокировки.
Ответ на комментарий
Хорошо, теперь я понял, вы правы. Но вы все еще блокируете на уровне приложения, что означает, что не должно иметь значения, какую транзакцию db выбирает ef. Чтобы два пользователя не могли разблокировать один и тот же объект, используйте блок блокировки C #, который я разместил выше.