Как безопасно увеличить счетчик в Entity Framework - PullRequest
7 голосов
/ 11 марта 2011

Допустим, у меня есть таблица, которая отслеживает количество загрузок файла, и я предоставляю эту таблицу своему коду через EF. Когда файл загружен, я хочу обновить счетчик на единицу. Сначала я написал что-то вроде этого:

var fileRecord = (from r in context.Files where r.FileId == 3 select r).Single();
fileRecord.Count++;
context.SaveChanges();

Но затем, когда я изучил фактический SQL, который генерируется этими операторами, я заметил, что увеличение происходит не на стороне БД, а в моей памяти. Таким образом, моя программа считывает значение счетчика в базе данных (скажем, 2003), выполняет вычисления (новое значение - 2004), а затем явно обновляет строку новым значением счетчика 2004. Очевидно, что это не безопасно с точки зрения параллелизма .

Я надеялся, что запрос будет выглядеть так:

UPDATE Files SET Count = Count + 1 WHERE FileId=3

Кто-нибудь может подсказать, как мне это сделать? Я предпочел бы не блокировать строку перед чтением, а затем разблокировать после обновления, потому что я боюсь блокировать чтения другими пользователями (если нет возможности заблокировать строку только для записей, но не для блоковых чтений).

Я также рассмотрел выполнение команды Entity SQL, но, похоже, Entity SQL не поддерживает обновления.

Спасибо

Ответы [ 2 ]

1 голос
/ 11 марта 2011

Вы можете вызывать хранимую процедуру с EF.Напишите sproc с указанным вами SQL, а затем создайте импорт функции в вашей модели EF, сопоставленной с указанным sproc.

0 голосов
/ 13 марта 2011

Вам нужно будет сделать некоторую блокировку, чтобы заставить это работать.Но вы можете минимизировать количество блокировок.

Когда вы читаете счетчик и хотите обновить его, вы должны заблокировать его, это можно сделать, поместив чтение и обновление в область транзакции.Это защитит вас от состояния гонки.

Когда вы читаете значение и хотите просто прочитать его, вы можете сделать это с уровнем изоляции транзакции ReadUncommited, и это чтение не будет заблокировано чтением /блокировка записи выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...