Sql server 2008 在SQL中使用TransactionScope with read uncommitted-是否需要使用(nolock)?

Sql server 2008 在SQL中使用TransactionScope with read uncommitted-是否需要使用(nolock)?,sql-server-2008,c#-4.0,nhibernate,transactions,fluent-nhibernate,Sql Server 2008,C# 4.0,Nhibernate,Transactions,Fluent Nhibernate,我使用的是FluentNHibernate,我有一个记录列表,映射到SQLServer2008视图。肮脏的阅读对我来说没问题,不锁定表格是优先考虑的 视图中的SQL查询没有任何with(nolock),但是,我使用以下方法 using (var txScope = new TransactionScope(TransactionScopeOption.Suppress, new TransactionOptions() { IsolationLevel = System.Transactions

我使用的是FluentNHibernate,我有一个记录列表,映射到SQLServer2008视图。肮脏的阅读对我来说没问题,不锁定表格是优先考虑的

视图中的SQL查询没有任何with(nolock),但是,我使用以下方法

using (var txScope = new TransactionScope(TransactionScopeOption.Suppress, new TransactionOptions() { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted })) { ... The reading of records from the view is done here, through Fluent NHibernate... } 使用(var txScope=newtransactionscope(TransactionScopeOption.Suppress,newtransactionoptions(){IsolationLevel=System.Transactions.IsolationLevel.ReadUncommitted})) { …通过Fluent NHibernate在此处读取视图中的记录。。。 } 将应用程序层的隔离级别设置为read uncommitted,是否与(nolock)一起应用于在该上下文中生成的查询?

简短回答:否

长答覆: 仅定义TransactionScope并不定义在事务中调用任何读或写操作

要在事务中运行某些内容,您仍然必须打开并提交事务

Timeout
IsolationLevel
的TransactionScope的
TransactionOptions
仅为范围内创建的任何事务定义默认值,而不显式设置这些选项。实际上,TransactionScope确实创建了一个事务,但如果不打开一个新事务,它将不会处于活动状态。在内部,这将做一些复杂的事情,克隆事务等。。。所以让我们忽略这个

如果没有事务,则无法定义隔离级别,任何select语句都将使用
IsolationLevel.ReadCommitted
运行,因为这是SQL Server的默认值

您还可以查询
session.Transaction.IsActive
,查看会话当前是否有活动的事务

让我们看一下下面的代码,我添加了一些注释以使其更加清晰

using (var scope = new TransactionScope(TransactionScopeOption.Required,
                    new TransactionOptions()
                    {
                        IsolationLevel = IsolationLevel.ReadUncommitted
                    }))
{

    using (var session = sessionFactory.OpenSession())
    {
        // outside any transaction...
        var x = session.Transaction.IsActive; // false;

        // read will be done with SQL Server default (ReadCommited)
        var pp = session.Query<Page>().Where(p => p.Photos.Count() > 1).ToList();

        using (var transaction = session.BeginTransaction())
        {
            // will use ReadUncommitted according to the scope
            var y = session.Transaction.IsActive; // true;

            var p1 = session.Get<Page>(1);

            transaction.Commit();
        }
        using (var transaction = session.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
        {
            // will use ReadCommitted according to the transaction initialization
            var y = session.Transaction.IsActive; // true;

            var p1 = session.Get<Page>(1);

            transaction.Commit();
        }

        scope.Complete();
    }
}
--


如果这些信息中的任何一个可能是错误的,请纠正我,我只是自己发现了这一点,因此可能存在一些失败的可能性;)

我不知道为什么,但TransactionScope代码对我不起作用

我用了这个密码。启动下面的新会话可确保您没有现有事务。(当然还有其他方法)

在NHibernate分析器中,我可以看到:

begin transaction with isolation level ReadUncommitted

审核登录
不是查看正在执行的命令的当前隔离级别的可靠方法。见我的评论。隔离级别的更改很难在探查器中查看,并且可能发生在审核登录行和正在考虑的SQL语句之间。这在divega的评论中得到了最好的解释!发生这种事很有趣。结果是,我的批处理作业中有一个太大的事务。我对事务进行了批处理,现在我不再需要肮脏的读取。(未提交)
        using (var session = _session.SessionFactory.OpenSession())
        using (var txn = session.BeginTransaction(IsolationLevel.ReadUncommitted))
        {
            // bunch of select statements.
        }
begin transaction with isolation level ReadUncommitted