【问题标题】:SET TRANSACTION ISOLATION LEVEL works only with transactions?SET TRANSACTION ISOLATION LEVEL 仅适用于事务?
【发布时间】:2016-10-13 01:09:20
【问题描述】:

在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;

更新: 根据Randy Levy's answer,我将更新我的查询如下:

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

这是为了克服possible isolation level leaks when using pooling。

【问题讨论】:

  • 您不需要交易。除非我弄错了,READ UNCOMMITTED 只是让 any 选择语句像使用 NOLOCK 提示一样工作。

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


【解决方案1】:

是的,即使不在显式BEGIN TRANSACTION 中,您也将从设置的事务隔离级别中受益。当您设置事务隔离级别时,它是在连接级别上设置的。

来自SET TRANSACTION ISOLATION LEVEL (Transact-SQL):

一次只能设置一个隔离级别选项,并且 在显式更改之前一直为该连接设置。

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

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

【讨论】:

  • 很好的收获,感谢您指出这一点!因为the default isolation level is READ COMMITTED,我认为按如下方式更新我的查询是有意义的:SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; SELECT * from MyTable; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; 然后我应该受到这个可能的错误的保护,因为我的目标是 SQL Server 2005+
【解决方案2】:

第一个

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * from MyTable

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

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

【讨论】:

  • 只想在需要多语句一致性的时候在REPEATABLE_READ和SNAPSHOT级别也需要添加显式事务,
  • 是的 - 我应该澄清一下,我只是以 SERIALIZABLE 为例。
  • @DanGuzman 你能链接到更多的信息吗?在测试中,我发现您所说的是真的,但这似乎与所选答案相矛盾,而且我在文档中没有看到任何地方说明是否必须开始交易。
【解决方案3】:

SQL Server 中的每条语句都在事务的上下文中运行。当你做类似的事情时

select * from [dbo].[foobar];

SQL Server 确实如此:

begin transaction;
select * from [dbo].[foobar];
commit;

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

【讨论】:

    猜你喜欢
    • 2022-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-05
    • 2023-03-26
    相关资源
    最近更新 更多