Операции Entity Framework с SQL - предотвращение тупиков - PullRequest
1 голос
/ 11 декабря 2010

У меня есть таблица в SQL Server, которая выглядит примерно так:

Col1  Id  -Int and Key    
Col2  ProductId  int    
Col3  ProductDesc   Varchar

В моем приложении Silverlight у меня есть две таблицы, показывающие данные из этой таблицы, отделенные ProductId. Другими словами, у меня есть все продукты A в одной сетке и все продукты B в другой сетке.

Когда я выбираю какой-либо элемент в любом гирде, я записываю его в таблицу. Если я отменяю выбор из скелета, я удаляю строку в отчете. Из-за использования в Silverlight асинхронных вызовов, когда одна сетка занята, пользователь все еще может работать с другой сеткой (что я и хочу). Однако, если пользователь отменяет выбор элементов из одной сетки, в то время как элементы вставляются из другой, я получаю ошибки взаимоблокировки.

Все мои вставки выполняются после того, как каждая сущность обновлена, и я сделал вызов SubmitChanges (). Удаления обрабатываются по-другому. Поскольку в EF нет DeleteAll, я использую метод ExecuteStoreCommand () в контексте объекта и отправляю запрос DELETE, что может быть связано с моей проблемой.

Как я могу использовать одну и ту же таблицу для достижения этой цели без ошибок взаимоблокировки? Я действительно пытаюсь избежать создания отдельной таблицы для каждой сетки.

Если бы я использовал EF для удаления из моих сущностей вместо ExecuteStoreCommand (), лучше ли EF обрабатывал бы взаимные блокировки? Похоже, что ресурс загружает таблицу в память, удаляя каждую строку по одной за раз.

РЕДАКТИРОВАТЬ: Я хотел добавить, что я убедился, что мои взаимоблокировки возникают, когда я удаляю из talbe в то же время, когда EF вставляет в него.

Спасибо

-Скотт

Ответы [ 3 ]

1 голос
/ 11 декабря 2010

Попробуйте использовать уровни изоляции для своих транзакций:

using (TransactionScope scope = 
          new TransactionScope(TransactionScopeOption.RequiresNew, 
             new TransactionOptions() 
             {
                IsolationLevel = IsolationLevel.ReadUncommitted 
             }))
{
   // read only work - no locks on records. effectively SELECT xx from xxx WITH (NOLOCK)
}

Однако AFAIK предназначен для контекстных запросов EF. Если вы используете ExecuteStoreCommand, то вам, возможно, придется вручную добавить подсказку NOLOCK к самому запросу.

0 голосов
/ 16 августа 2013

У меня работает следующее.

using (var context = new XXX())   // Replace XXX with your specifics
{
  context.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;"); 
  // your LINQ code here
}
0 голосов
/ 11 декабря 2010

Ваш оператор удаления касается тех же строк, что и другие операции?

Если нет, попробуйте добавить подсказку о блокировке строки: удалить из xyz с помощью (rowlock), где ...

...