LinqToSql. Тупик при обновлении строки. Parallel.For
У меня проблема. Я пытаюсь обновить базу данных, используя параллель. Вот код:
Parallel.For(rCnt, range.Rows.Count + 1, (jrCnt, loopState) =>
{
var prcI = new Price(); // new
/*bla bla bla bla - bla bla - bla bla - bla */
if ((!string.IsNullOrEmpty(prcI.name)) && (prcI.prc != 0)) // process add or update
{
prcI.company = nameprice;
prcI.date = datatimeselect.Text;
Accessor.AddProductUpdateProduct(prcI); // main func
/*bla bla bla bla - bla bla - bla bla - bla bla - bla */
}
Вот поле кода функции для обновления:
public static bool AddProductUpdateProduct(Price price)
{
bool add = false;
var db = new PriceDataContext();
var matchedprod =
db.Price.Single(x => x.name == price.name && x.date != price.date && x.company == price.company); // find match
if (matchedprod != null) // match FOUnDE
{
if (matchedprod.prc != price.prc)
{
matchedprod.date = price.date;
matchedprod.prc = price.prc;
}
else
{
matchedprod.date = price.date;
}
db.SubmitChanges(); // DEADLOCK is her!!!
}
/*bla - bla bla - bla bla - bla bla - bla bla - bla */
}
Когда я создаю запись, все хорошо!
Спасибо!
2 ответа
При количестве записей от 3000 до 10000 (комментарии) я бы искал решение, которое использовало бы SqlBulkCopy для переноса данных в промежуточную таблицу (т. Е. Таблицу, которая выглядит аналогично данным, которыми вы манипулируете, но не является частью вашего ядра). модель). Это наиболее эффективный способ передачи большого количества данных на сервер (хотя вы также можете посмотреть на параметры с табличными значениями).
Имея данные на сервере, я бы затем сделал либо одно обновление (внутреннее объединение) и одну вставку (где не существует), либо одну "загрузку" (доступно в SQL Server 2008 и более поздних версиях).
При этом используется меньше ресурсов ЦП на сервере приложений, меньше сети и меньше ресурсов базы данных. Кроме того, поскольку во вставке / обновлении задействован только один SPID, отсутствует риск взаимоблокировки.
Я думаю, что это может быть та же проблема, которую я описал в этом вопросе Deadlock на SELECT / UPDATE. Это не проблема с linq to sql. Проблема с linq to sql в том, что вы не можете легко выполнить выбор с помощью Updlock.