SET TRANSACTION ISOLATION LEVEL 仅适用于交易?
SET TRANSACTION ISOLATION LEVEL works only with transactions?
在 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;
更新:
根据 ,我将更新我的查询如下:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * from MyTable;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
这是为了克服possible isolation level leaks when using pooling.
第一个
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * from MyTable
会起作用。您设置的事务级别适用于每个后续事务,您的SELECT语句是其自身的隐式事务。
如果您需要确保多次读取过程中的某种程度的一致性,您只需要显式启动一个事务。例如,如果您使用 SERIALIZABLE,那么您可以将多个 SELECT 包装在一个事务中,并确保在您读取它时不修改基础数据。
SQL 服务器中的每个语句在事务上下文中都是 运行。当你做类似
的事情时
select * from [dbo].[foobar];
SQL 服务器确实如此:
begin transaction;
select * from [dbo].[foobar];
commit;
因此,设置明确的事务隔离级别确实会影响事务。甚至是数据库引擎代表您启动的隐含的!
是的,即使不在显式 BEGIN TRANSACTION
内,您也会受益于您设置的事务隔离级别。当您设置事务隔离级别时,它是在连接级别上设置的。
来自SET TRANSACTION ISOLATION LEVEL (Transact-SQL):
Only one of the isolation level options can be set at a time, and it
remains set for that connection until it is explicitly changed.
可能发生的一个 "gotcha"(问题)是使用池时隔离级别可能会在不同连接之间泄漏。如果您在一个(或某些)特定代码段中显式设置隔离级别(但在大多数其他地方使用默认设置)并且还使用连接池。如果代码期望默认隔离级别 "A" 但获得了隔离级别显式设置为 "B" 的连接,这可能会导致奇怪的问题。
看来这个问题现在已在 SQL 服务器的更高版本中修复:SQL Server: Isolation level leaks across pooled connections
在 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;
更新:
根据
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * from MyTable;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
这是为了克服possible isolation level leaks when using pooling.
第一个
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * from MyTable
会起作用。您设置的事务级别适用于每个后续事务,您的SELECT语句是其自身的隐式事务。
如果您需要确保多次读取过程中的某种程度的一致性,您只需要显式启动一个事务。例如,如果您使用 SERIALIZABLE,那么您可以将多个 SELECT 包装在一个事务中,并确保在您读取它时不修改基础数据。
SQL 服务器中的每个语句在事务上下文中都是 运行。当你做类似
的事情时select * from [dbo].[foobar];
SQL 服务器确实如此:
begin transaction;
select * from [dbo].[foobar];
commit;
因此,设置明确的事务隔离级别确实会影响事务。甚至是数据库引擎代表您启动的隐含的!
是的,即使不在显式 BEGIN TRANSACTION
内,您也会受益于您设置的事务隔离级别。当您设置事务隔离级别时,它是在连接级别上设置的。
来自SET TRANSACTION ISOLATION LEVEL (Transact-SQL):
Only one of the isolation level options can be set at a time, and it remains set for that connection until it is explicitly changed.
可能发生的一个 "gotcha"(问题)是使用池时隔离级别可能会在不同连接之间泄漏。如果您在一个(或某些)特定代码段中显式设置隔离级别(但在大多数其他地方使用默认设置)并且还使用连接池。如果代码期望默认隔离级别 "A" 但获得了隔离级别显式设置为 "B" 的连接,这可能会导致奇怪的问题。
看来这个问题现在已在 SQL 服务器的更高版本中修复:SQL Server: Isolation level leaks across pooled connections