在数据库事务中更改隔离级别是可以的,包括将一个事务加入到已运行的事务中。 你只需改变处理锁的方式。使用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我忽略了的内容,还是因为无法保证对所有可能的注册资源进行合理的行为而导致这样的结果?