为什么内层TransactionScope的隔离级别不能不同,而SQL事务可以呢?

3

在数据库事务中更改隔离级别是可以的,包括将一个事务加入到已运行的事务中。 你只需改变处理锁的方式。使用Sql Server,这可以无问题运行:

begin transaction 
set transaction isolation level serializable;
select * from FooTable;

set transaction isolation level read committed;
select * from FooTable;

begin transaction
set transaction isolation level serializable;
select * from FooTable;
--transaction_isolation_level can be observed as 4 (serializable)

然而,当使用.NET的TransactionScope在Sql Server中创建事务时,可以如下方式实现(使用C#和xUnit):

[Theory]
[AutoFixtureMagicToGetParameterInstances]
void ZmenaIzolacniUrovneVedeKVyjimce(IFooDao sut, Foo foo)
{
    var tranOpts = new TransactionOptions()
    {
        IsolationLevel = IsolationLevel.Serializable,
        Timeout = TimeSpan.FromSeconds(60)
    };
    var tranOpts2 = new TransactionOptions()
    {
        IsolationLevel = IsolationLevel.ReadCommitted,
        Timeout = TimeSpan.FromSeconds(60)
    };
    using (var transactionScope = new TransactionScope(TransactionScopeOption.Required, tranOpts))
    {
        sut.SelectFoos();
        using (var transactionScope2 = new TransactionScope(TransactionScopeOption.Required, tranOpts2))
        {
            sut.SelectFoos();
        }
    }
}

导致异常:

System.ArgumentException : The transaction specified for TransactionScope has a different IsolationLevel than the value requested for the scope.
 Parameter name: transactionOptions.IsolationLevel

为什么TransactionScope的设计者认为立即抛出异常是必要的?

我期望只涉及数据库资源时行为至少相同。 是否有关于TransactionScope我忽略了的内容,还是因为无法保证对所有可能的注册资源进行合理的行为而导致这样的结果?


1
这个回答解决了你的问题吗?如何使用不同的IsolationLevel实现内部TransactionScope? - pinkfloydx33
不是真的。这基本上是同样的问题 - 所以我很抱歉,我应该搜索更多,我期望这样的问题提到异常的唯一部分。但是“为什么在这里改变隔离级别是可以的,但在那里不行”的答案也不存在(正如OP在评论中指出的那样):(所以,不,它并没有真正回答这个问题。 - Igand
我将它标记为重复的问题。"这个答案是否解决了您的问题"是 Stack Overflow 在标记重复问题时更新的自动评论文本的一部分。 - pinkfloydx33
我明白了。现在我注意到,在被接受的答案下面有一个比较可接受的评论 - 这不过是我在问题的最后一段中提到的,但我猜想没有人会再添加更多内容了。我想我应该投票关闭我的问题并在那里编辑答案,这样下次它就更加显眼了? - Igand
我同意。由于细微之处,我决定将对我最有启发性的部分——评论——提取出来作为答案。我希望我的帖子以这种方式增加更多信息而不是混乱。 - Igand
显示剩余2条评论
1个回答

0

如此在这里的评论中所述 Inner TransactionScope with different IsolationLevel, how can it be achieved?

TransactionScope不仅限于与SQL Server一起使用,它可以允许跨进程/系统进行分布式事务。因此,它比SQL Server允许的更严格,可能简化了确保系统间一致性而不是支持分布式事务的复杂性。- AaronLS

因此,答案基本上归结为“TransactionScope 可能有更多任务要处理,而不仅仅是数据库事务,因此它禁止像更改隔离级别这样的复杂操作。”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接