2016-06-28 3 views
0

Я занимаюсь разработкой электронной коммерции с помощью c. 10000 продуктов, каждая из которых имеет 15 сортов, каждая из которых имеет уникальную цену, чтобы соответствовать, поэтому c. 150 000 цен на продукцию. Цены меняются каждый день, и они отправляются нам в CSV, и мы автоматизируем импорт, чтобы переписать всю таблицу базы данных по новым ценам, так как более 95% цен будет меняться каждый день. Из-за числа у нас есть флаг против каждой цены, указывающий, является ли эта цена той, что видна на веб-сайте.Как обойти «Ожидание ожидания»

После того, как мы импортируем, цены, которые были на сайте вчера (и, следовательно, отмечены как видимые), а цены, которые являются новыми, а не на сайте, имеют свои флаги, включенные в программу линии консоли C#, с этим LINQ команда: -

db.Database.ExecuteSqlCommand("UPDATE [MyDatabase].[dbo].[ProductVariationPrice] SET IsVisible = IsVisible^1"); 

поэтому все, что было отмечено как IsVisible, теперь не видно и наоборот. Это занимает менее секунды даже для 300 000 строк, а затем мы удаляем диапазон строк, которые установлены в IsVisible = 1.

Перед этим мы используем BulkInsert для быстрого ввода строк, а LINQ's RemoveRange для удаления невидимых элементов быть удаленным.

Первоначально это было прекрасно, но теперь я получаю пользователей, которые находятся на сайте электронной торговли, получают ошибку «Ожидание операции с задержкой» в точный период, когда флаги данных переходят и старые данные удаляются ,

Как я могу остановить этот тайм-аут ожидания ожидания в течение этого периода? Вещи мне сказали, что мы не можем сделать: -

  • Обновление каждая запись вместо переписывания всей таблицы (занимает слишком долго)
  • Блокировка всех из системы в течение периода в то время как новые цены войдите в систему.

Может ли кто-нибудь посоветовать? Является ли это продолжением подключения базы данных дольше?

Заранее благодарен!

UPDATE Вот полный код вокруг узкого места: -

using (TransactionScope transaction = new TransactionScope()) 
{ 
    lwc.Database.ExecuteSqlCommand("UPDATE [MyDatabase].[dbo].[ProductVariationPrice] SET IsVisible = IsVisible^1"); 
    transaction.Complete(); 
} 

List<ProductVariationPrice> oldProductPrices = db.ProductVariationPrices.Where(x => !x.IsVisible).ToList(); 
db.ProductVariationPrices.RemoveRange(oldProductPrices); 
db.SaveChanges(); 
+0

Как долго длится удаление?это в транзакции? если да, то что еще в транзакции? какие вещи выходят из строя? по-видимому, это относится к аналогичным данным - каков уровень изоляции прочитанных запросов? и каков уровень изоляции запросов на запись? и уровень изоляции транзакции (транзакций)? –

+0

Привет, неуверенный, на каких уровнях изоляции (позвольте мне google). Переключатель SQL, который вы видите выше, находится внутри транзакции. Удалить не будет. Это может быть проблема? Страницы, которые терпят неудачу, являются страницей корзины заказов, по-видимому, потому, что она возвращает те же цены ...? Удаление занимает не более минуты или двух. –

+2

, если вы используете LINQ-to-SQL или Entity Framework (вы упоминаете LINQ, но это неоднозначно), тогда он будет использовать транзакцию автоматически, когда вы вызываете 'SubmitChanges()' (или что-то еще) - так что да, это было бы абсолютно проблемой. По какой-то причине вы не можете просто использовать один «DELETE ... WHERE ...» здесь? –

ответ

0

Изменить свой подход. Вам не нужно удалять записи и вставлять их снова. Операция вставки не менее дорогостоящая, чем обновление (на самом деле это зависит от нескольких факторов). И уже запрещенная идея обновления записей из кода C# ужасна. Вместо этого, сделать это следующим образом:

Import the CSV file to additional, working table in the database.

Не забудьте добавить первичный ключ. Если вам не нужен журнал транзакций по обновлениям, используйте TRUNCATE или просто DROP и заново создайте рабочую таблицу. Это будет намного быстрее, чем строки DELETE. Также рассмотрите использование таблицы TEMPORARY.

Write a query to update the records in the original table by joining the records in the working/TEMPORARY table you just imported.

Это было бы его.

Конечно, вы можете использовать свой флаг IsVisible, в зависимости от вашей ситуации, но я думаю, он больше не понадобится.

+0

Спасибо за ваши комментарии. Я задавался вопросом о временных таблицах и «TRUNCATE». Но если бы я уселся, разве у меня не было бы периода, когда цены вообще не были бы? –

+1

Я имел ввиду «TRUNCATE» временную таблицу перед каждым импортом; а не оригинальной. См. ... выполнить все грязные операции на стороне стола. После того, как у вас есть текущая цена рядом с ПК во временной таблице, выведите инструкцию 'UPDATE' в основную таблицу с' INNER JOIN' во временную таблицу на PK. –