Являются ли примитивы синхронизации бесполезными в TransactionScopes с асинхронными / ожидающими вызовами?

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

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

0 ответов

Другие вопросы по тегам