Являются ли примитивы синхронизации бесполезными в TransactionScopes с асинхронными / ожидающими вызовами? - PullRequest
0 голосов
/ 20 декабря 2018

Я считаю, что все примитивы синхронизации на основе потоков бесполезны в неявных транзакциях.Учитывая класс:

public class Country : IEnlistNotification
{
  public ReaderWriterLockSlim Lock { get; } = new ReaderWriterLockSlim();
  public void Commit(Enlistment enlistment)
  {
      this.Lock.ExitWriteLock();
  }
}

У меня есть следующий код:

using (TransactionScope transactionScope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
  Country country = new Country();
  Transaction.Current.EnlistVolatile(country, EnlistmentOptions.None);
  country.Lock.EnterWriteLock();

  await dbContext.Countries.AddAsync(newCountry).ConfigureAwait(true);
  await dbContext.SaveChangesAsync().ConfigureAwait(true);

  transactionScope.Complete();
}

Проблема в том, что, даже используя ConfigureAwait (true) , выне гарантированно вернуться в той же теме.Таким образом, хотя транзакция может завершиться в другом потоке, когда она вызывает методы Commit или Rollback для энергозависимых ресурсов и пора выходить из блокировок, она (часто) находится в другом потоке, нежели когда вы ввели блокировку.

Нет абсолютно никакого способа снять блокировку, и вы скоро будете заблокированы.Похоже, что ReaderWriterLockSlim и остальные примитивы довольно бесполезны в архитектуре, использующей шаблон асинхронности / ожидания.Я что-то упускаю из виду?

...