Workflow Foundation Сообщения ExternalDataExchange ставятся в очередь и являются транзакционными? - PullRequest
3 голосов
/ 09 апреля 2009

Я недавно работал с некоторыми средствами связи на основе ExternalDataExchange в WF. Насколько я понимаю, при работе с длительными (в данном случае конечным автоматом) рабочими процессами связь ставится в очередь, долговечна и транзакционна.

Я использую постоянство SQL и EventArgs, помеченные как «WaitForIdle = true».

Я бы предположил, что когда я делаю что-то вроде этого:

using(TransactionScope scope = new TransactionScope())
{
     IMyEDEService service = wfRuntime.GetService<IMyEDEService>()
     service.MyMethod(wfInstanceGuid, "Here's some data");
     DoSomeDatabaseWork();
} //Dispose causes scope to rollback

Я ожидаю, что мое событие не сработает в рабочем процессе. Похоже, что он действительно доставлен, так что это заставляет меня поверить, что это не транзакция. Вы могли видеть, как данные, зафиксированные в базе данных в DoSomeDatabaseWork (), откатываются, но перемещение рабочего процесса может быть плохим.

Может ли кто-нибудь подтвердить это, и если да, есть ли у вас обходной путь для сделать сообщение транзакционным?

На самом деле я хочу одну из этих двух вещей:

  1. Рабочий процесс не должен реагировать на сообщение, которое я поставил в очередь посредством внешнего обмена данными, до тех пор, пока транзакция, которая ставит сообщение в очередь, не будет зафиксирована (так же, как брокер служб в SQL-сервере).

- или -

  1. Если рабочий процесс начинает действовать на доставленном мною событии, он также должен выполнить откат. Я не вижу, как это могло бы произойти, используя планировщик по умолчанию, все же. Мне бы хотелось, чтобы выполнение рабочего процесса оставалось асинхронным, поэтому я не хочу выключать планировщик, если мне не нужно.

1 Ответ

2 голосов
/ 14 апреля 2009

Здесь происходит несколько проблем. Во-первых, когда вы используете постоянство SQL, уведомление рабочего процесса о событиях и наличие событий публикации рабочего процесса является постоянным и асинхронным, а базовый процесс рабочего процесса является транзакционным ... но не так, как вы думаете.

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

Использование области транзакции, как вы делали выше, хорошо, но вы должны помнить, что единственные области действия транзакции действительно работают, когда классы в блоке using знают область транзакции.

То, что вы можете сделать, это сделать так, чтобы ваш вызов MyMethod обернул вещи в блок try / catch. Когда что-то идет не так, вы можете проголосовать за откат ... но это все равно не отменяет вызов метода в EDES.

Если вы можете дать некоторые подробности о том, что вы пытаетесь выполнить на более высоком уровне, могут быть некоторые вещи, присущие WF, которые могут вам лучше подойти, чем попытка включить область действия транзакции в смесь.

Редактировать

Я немного покопался и нашел пару разных мест, где нам говорят, что нет API для управления очередью работы планировщика . К сожалению, для нас это означает, что любое поведение отката, которое мы хотим, нам придется выполнять самостоятельно.

Если бы я знал больше о том, почему вы пытались откатить работу, поставленную в очередь через EDES, я мог бы предложить некоторые потенциальные архитектуры для выполнения вашей задачи без повторного изобретения колеса (транзакций).

9 раз из 10, когда я сталкиваюсь с подобными проблемами, когда кажется, что WF просто не поддерживает то, что я пытаюсь сделать, проблема в том, что я либо оставил слишком много кода снаружи рабочий процесс или попытка поместить слишком много кода в его и рефакторинг, где моя работа выполнена, часто решает мою проблему, не требуя от меня писать новые вещи.

...