sql-server – 在NOLOCK上使用ADO.NET TransactionScope vs ExecuteCommand的高容量站点,直接READ UNCOMMITTED?

请阅读Omar在他的博客Linq to SQL solve Transaction deadlock and Query timeout problem using uncommitted reads 和最后的这篇有趣的文章
Javed Hasan开始与他讨论他在高容量网站上解决nolock情况的问题.

在这里,试图解决的问题是,从sql意义上我们需要使用带有NOLOCK的Select语句或使用SET TRANSACTION LEVEL READ UNCOMMITTED,否则在DB中的高容量行将被锁定并导致错误. Omar使用的技术是Linq2Sql,所以问题是我们如何在你的C#数据访问代码中实现这一点,所以上述情况不会发生?

基本上在帖子中,Omar通过在现实世界网站上使用SqlProfiler等工具进行工作和测试来解决他的问题,而Javed Hasan则使用MSDN文档和Scott Hanselman的博客文章等来解决他的问题.

奥马尔建议使用以下内容

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();
}

而Javed Hasan表示

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

我非常有兴趣知道你们在这个特定问题上你们在StatckOverflow这样的高容量网站上做了什么,或者杰夫和他们的家伙在这方面做了什么?

编辑:在阅读完第一篇文章后,我想在奥马尔的帖子中指出一些内容.

>他确实遇到了与他的方法有关的问题,但是他解决了这个问题,看到了他的帖子.
>更重要的是,他提到他尝试使用ADO.NET Transaction方式,甚至尝试了Scott Hanselman在他的博客上写的内容,但它不适用于高容量网站,它会降低性能. Omar说这个“System.Transactions有很大的开销.我从来没有能够在高容量网站上使用它而不会使CPU达到100%而Req / sec降到1/10.它是为企业应用程序而不是高卷网站.“

最佳答案
首先请避免未提交的读取,它们可能会导致很多问题.一个更好的方法是将数据库设置为snapshot isolation.这就是Jeff所做的.

Jeff基本上说:“bla bla bla,be real,bla bla bla,数据库理论家,bla bla bla,READ UNCOMMITTED对于不需要数据一致性的REAL生产应用程序非常有用.” Jeff不是DBA,幸运的是,SO上有很多DBA.

Omar方法的问题在于它可能会将“读取未提交”隔离级别的连接泄漏到您的连接池中,这可能会对您的网站造成严重破坏.含义随机语句可以在未提交的读取中执行.

Javed方法会好得多,因为在处置MS上有机会清理连接上的东西.

编辑如果您遇到Javed方法的性能问题,您可以考虑滚动自己的事务管理器.

你可能想做的一些事情:

>保持一堆当前交易
>提交事务时确认您在创建者线程上
>将事务隔离重置为dispose上的先前状态
>如果未提交事务,则回滚处理.
>支持嵌套回滚.

转载注明原文:sql-server – 在NOLOCK上使用ADO.NET TransactionScope vs ExecuteCommand的高容量站点,直接READ UNCOMMITTED? - 代码日志