Почему IsolationLevel внутреннего TransactionScope не может быть другим, а SQL транзакций - другими? - PullRequest
3 голосов
/ 09 мая 2020

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

1 Ответ

0 голосов
/ 10 мая 2020

Как указано в комментариях здесь Внутренний TransactionScope с другим IsolationLevel, как это может быть достигнуто?

TransactionScope не ограничивается использованием с SQL Сервером, он может позволить распределенные транзакции между процессами / системами. Таким образом, он строже, чем позволяет SQL Server, что, вероятно, упростит задачу обеспечения согласованности между системами, чем поддержка распределенных транзакций. - AaronLS

Таким образом, ответ, похоже, сводится к следующему: «TransactionScope может иметь гораздо больше, чем просто транзакцию базы данных, и поэтому он запрещает такие сложности, как изменение уровней изоляции».

...