SET TRANSACTION ISOLATION LEVEL仅适用于交易?

时间:2016-10-12 00:04:59

标签: c# sql-server transactions isolation-level

official example here中,我们将SET TRANSACTION ISOLATION LEVEL与明确定义的交易结合使用。

我的问题是,如果我从SqlCommand执行查询,例如:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * from MyTable

我会从我设置的新隔离级别中受益吗?

或者我是否需要明确定义这样的交易?

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN TRANSACTION;
    SELECT * from MyTable
COMMIT TRANSACTION;

更新 根据{{​​3}},我将按如下方式更新我的查询:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * from MyTable;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

这是为了克服Randy Levy's answer

3 个答案:

答案 0 :(得分:2)

是的,即使不在明确的BEGIN TRANSACTION范围内,您也可以从您设置的事务隔离级别中受益。设置事务隔离级别时,它将在连接级别设置。

来自SET TRANSACTION ISOLATION LEVEL (Transact-SQL)

  

一次只能设置一个隔离级别选项   仍然为该连接设置,直到明确更改为止。

可能发生的一个“问题”(问题)是在使用池时隔离级别可能在不同连接之间泄漏。如果您在一个(或某些)特定代码段中明确设置隔离级别(但使用默认的大多数其他位置)并使用连接池。如果代码需要默认隔离级别“A”但是获得隔离级别明确设置为“B”的连接,则会导致奇怪的问题。

现在,SQL Server的更高版本中已修复此问题:SQL Server: Isolation level leaks across pooled connections

答案 1 :(得分:1)

第一个

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * from MyTable

会奏效。您设置的事务级别适用于每个后续事务,您的SELECT语句是它自己的隐式事务。

如果需要确保多次读取的某种程度的一致性,则只需要显式启动事务。例如,如果您使用SERIALIZABLE,那么您可以在事务中包装多个SELECT,并确保在您阅读它时不会修改基础数据。

答案 2 :(得分:1)

SQL Server中的每个语句都在事务的上下文中运行。当你做

之类的事情
 public class GChartsDataTbl
{
    public List<Col> cols { get; set; }
    public List<Row> rows { get; set; }
}
public class Col
{
    public string id { get; set; }
    public string type { get; set; }
}

public class C
{
    public string v { get; set; }
    public object f { get; set; }
}

public class Row
{
    public List<C> c { get; set; }
}

SQL Server确实这样做:

select * from [dbo].[foobar];

因此,设置显式事务隔离级别 会影响事务。甚至是数据库引擎代表你启动的隐含的!