在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。
答案 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];
因此,设置显式事务隔离级别 会影响事务。甚至是数据库引擎代表你启动的隐含的!