可以在数据库事务中更改隔离级别,包括将一个事务加入已经运行的事务的情况。从现在开始,您只需更改处理锁的方式即可。使用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的信息,或者仅仅是因为不能保证所有可能使用的资源上的合理行为?
如此处Inner TransactionScope with different IsolationLevel, how can it be achieved?的评论所述
TransactionScope不限于与SQL Server一起使用,它可以允许跨进程/系统的分布式事务。所以比较严格超出SQL Server的允许范围,可能会简化确保整个系统的一致性,而不是分布式支持交易。 – AaronLS
所以答案基本上可以归结为“ TransactionScope may的作用远不止于数据库事务,因此它禁止诸如更改隔离级别之类的复杂性”。