Сайт большого объема с использованием ADO.NET TransactionScope и ExecuteCommand для NOLOCK, ЧИТАТЬ НЕОБЕСПЕЧЕННЫЕ напрямую - PullRequest
5 голосов
/ 09 марта 2009

Просто прочитайте эту интересную статью Омара в своем блоге 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 и даже попробовал то, что Скотт Хансельман написал в своем блоге, но это не работает для сайта с большими объемами, это несколько снижает производительность. Омар сказал, что «System.Transaction имеет значительные накладные расходы. Я никогда не мог использовать его на больших сайтах без того, чтобы процессор работал на 100%, а Req / sec снижался до 1/10. Это сделано для корпоративных приложений, а не для высоких». объем сайтов. "

Ответы [ 4 ]

9 голосов
/ 10 марта 2009

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

Джефф в основном сказал: «Бла-бла-бла, будьте реальными, бла-бла-бла, теоретиками баз данных, бла-бла-бла, READ UNCOMMITTED может быть полезным для реальных приложений, которые не требуют согласованности данных». Джефф не администратор баз данных, к счастью, на SO здесь много администраторов баз данных.

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

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

РЕДАКТИРОВАТЬ Если у вас возникли проблемы с производительностью в подходе Javed, вы можете посмотреть на свой собственный менеджер транзакций.

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

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

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

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

1 голос
/ 31 июля 2009

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

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

0 голосов
/ 20 апреля 2011

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

...