Изменение уровня изоляции внутри транзакции базы данных - это нормально, включая случай, когда вы присоединяете одну транзакцию к уже запущенной. С этого момента вы просто меняете способ обращения с замками. При использовании сервера Sql это работает без проблем:
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 сервере, как это (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, которое мне не хватает, или это просто потому, что разумное поведение не может быть гарантировано для всех возможных задействованных ресурсов?