Сайт большого объема, использующий ADO.NET TransactionScope против ExecuteCommand при NOLOCK, СЧИТЫВАЕТ НЕЗАФИКСИРОВАННЫЕ данные напрямую?

StackOverflow https://stackoverflow.com/questions/628004

Вопрос

Просто прочтите эту интересную статью Омара в его блоге Linq to SQL решает проблему взаимоблокировки транзакций и тайм-аута запроса с помощью незафиксированных операций чтения и в конце Джавед Хасан начал спорить с ним о его решении ситуации с блокировкой на сайте большого объема.

Здесь проблема, которую пытаются решить, заключается в том, что с точки зрения sql нам нужно использовать инструкции Select с NOLOCK или использовать SET TRANSACTION LEVEL READ UNCOMMITTED, иначе при большом объеме строки в БД будут заблокированы и вызовут ошибки.Технология, которую использовал Омар, - Linq2SQL, поэтому вопрос в том, как нам добиться этого в вашем коде доступа к данным на C #, чтобы описанного выше не произошло?

В основном в этом посте Омар приходит к своему решению, работая и тестируя на реальном сайте и с помощью таких инструментов, как SqlProfiler, в то время как Джавед Хасан приходит к своему решению с документами MSDN и сообщением в блоге Скотта Хансельмана и т.д.

Омар предлагает использовать следующее

using (var db = new DropthingsDataContext2())
{
  db.Connection.Open();
  db.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");

  var user = db.aspnet_Users.First();
  var pages = user.Pages.ToList();
}

принимая во внимание , что Джавед Хасан предлагает

using (new TransactionScope(TransactionScopeOption.Required, 
  new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted }))
{
 //Your db Operation
}

Мне очень интересно узнать, что вы, ребята, делаете по этому конкретному вопросу на таком массовом сайте, как StatckOverflow, или что Джефф и их ребята сделали в этом отношении?

Редактировать:Прочитав первый пост, я хочу обратить внимание на несколько вещей в посте Омара.

  1. он действительно столкнулся с проблемой подключения при своем подходе, но он решил ее, смотрите его пост.
  2. что еще более важно, он упомянул, что пробовал использовать ADO.NET Способ транзакции и даже попробовал то, что Скотт Хансельман написал в своем блоге, но это не работает для сайтов большого объема, это немного снижает производительность.Омар сказал, что эта "Система.Транзакции сопряжены со значительными накладными расходами.Мне никогда не удавалось использовать его на веб-сайте большого объема без того, чтобы процессор не работал на 100%, а производительность в секунду снизилась до 1/10.Он создан для корпоративных приложений, а не для сайтов большого объема ".
Это было полезно?

Решение

Прежде всего, пожалуйста, избегайте незафиксированных операций чтения, они могут вызвать множество проблем.Гораздо лучший подход - просто установить базу данных в изоляция моментального снимка. Это то , что сделал Джефф.

Джефф в основном сказал:"бла-бла-бла, будьте настоящими, бла-бла-бла, теоретики баз данных, бла-бла-бла, ЧТЕНИЕ UNCOMMITTED может быть полезно для РЕАЛЬНЫХ производственных приложений, которым не нужна согласованность данных ". Джефф не является администратором базы данных, к счастью, здесь, на SO, есть много администраторов баз данных.

Проблема с подходом Omar заключается в том, что он может привести к утечке соединений с уровнем изоляции "read uncommitted" в ваш пул подключений, что может привести к хаосу на вашем веб-сайте.Значение случайного оператора может быть выполнено в режиме read uncommitted.

Подход Javed был бы намного лучше, потому что при dispose у MS есть возможность очистить данные в соединении.

Редактировать Если у вас возникли проблемы с производительностью при использовании подхода Javed, вы могли бы рассмотреть возможность создания собственного менеджера транзакций.

Некоторые вещи, которые вы, вероятно, хотите сделать:

  • Хранить стопку текущих транзакций
  • Подтвердите, что вы находитесь в потоке создателя, когда транзакция будет зафиксирована
  • Сбросьте изоляцию транзакции до ее предыдущего состояния при dispose
  • Откат при удалении, если транзакция не была зафиксирована.
  • Поддержка вложенных откатов.

Другие советы

Я разработчик в команде инструментов группы SQL Server в Microsoft.Многие приложения не слишком чувствительны к согласованности транзакций, особенно если вы пишете приложение, которое создает отчеты или что-то еще, где иногда противоречивые данные - это еще не конец света.Конечно, если вы пишете финансовое приложение или что-то еще, имеющее очень низкую устойчивость к несогласованности данных, вы, вероятно, захотите изучить другие решения.

Если вы решите использовать незафиксированные чтения, у меня есть написал в блоге удобное решение использование методов расширения в C #.

{Моя (плохая) репутация не позволяет мне публиковать комментарии, поэтому я помещаю это в качестве ответа}

Если вы используете IsolationLevel через System.Transactions и создаете новый контекст Linq в блоке transaction, SQL Server в конечном итоге пытается вызвать DTC для координации транзакции.Это только что случилось со мной и было совершенно неожиданно.

Что касается транзакций в .Net и (почему-то неожиданного) побочного эффекта DTC, этот документ Знакомство с системой.Транзакции в .NET Framework 2.0 автор: Юваль Лоуи, все очень хорошо объясняет и по-прежнему полностью актуален (.Net4).Стоит почитать.(Я бы также разместил комментарий...если бы я мог.)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top