У меня есть служба WCF, которая включает операцию, отмеченную OperationBehavior(TransactionScopeRequired=true)
и TransactionFlow(TransactionFlowOption.Allowed)
.
Клиент этого сервиса также является частью транзакции (у него также есть база данных. Это упрощенный пример), так что это включает в себя распределенные транзакции и 2-phase-commit.
Чтобы мои операции с базами данных поддерживали двухфазную фиксацию, я реализовал интерфейс IEnlistmentNotification.
На этапе подготовки я записываю данные в БД с тегом транзакции, а на этапе фиксации удаляю тег транзакции из данных. Обратите внимание, что этап фиксации включает в себя доступ к базе данных, поэтому он может быть немного медленным.
Проблема в том, что из того, что кажется и из того, что я прочитал, фаза фиксации запускается асинхронно, поэтому, например, следующий последовательный сценарий может не работать:
1) Транзакция 1: Клиент вставляет A
2) Транзакция 2: Клиент вставляет B, который полагается на A (сервер ищет A, извлекает из него информацию и использует ее для вставки B)
Поскольку фаза принятия транзакции 1, возможно, еще не завершилась на стороне сервера, транзакция 2 может не найти A (поскольку она все еще помечена тегом «транзакция 1»).
Эти 2 транзакции могут быстро происходить одна за другой, поэтому это вопрос состояния гонки.
Я заметил, что когда я включил ведение журнала моего драйвера БД, фиксация стала немного медленнее, и во 2-й транзакции произошла ошибка. Если я отключил ведение журнала, то это удалось. Но даже если я отключу ведение журнала, это все равно зависит от состояния гонки, и я бы не стал полагаться на это в производственной среде.
Как лучше всего решить эту проблему?