Сбой транзакций NES (.NET Event Sourcing)?

Я пробую NES 0.3 (https://github.com/elliotritchie/NES), но не могу понять, что происходит. Я запускаю пример приложения, в котором я изменил конфигурацию EventStore на сервер SQL и вставил исключение непосредственно перед тем, как выполнение покидает SendMessageCommandHandler.Handle().

Затем я запускаю обработчик и веб-сайт. Я создаю нового пользователя, который идет хорошо. Одно событие зарегистрировано в моей таблице EventStore. Затем я пытаюсь отправить сообщение. Это не удается из-за моего исключения. Таким образом, событие NServiceBus не было отправлено из-за транзакционного характера шины. НО в EventStore событие регистрируется и помечается как dispatched=1.

Что мне не хватает? Конечно, он не должен был быть зарегистрирован как отправленный, если он не был отправлен NServiceBus? Единственное сообщение в очереди ошибок — «SendMessageCommand». Вероятно, я неправильно понимаю, поэтому я решил спросить здесь, прежде чем сообщать об этом как о проблеме автору.


person Werner    schedule 24.08.2011    source источник


Ответы (2)


Версия NES 0.3.0.1 http://nuget.org/List/Packages/NES будет теперь фиксируйте любые изменения только после того, как все ваши обработчики успешно запустились.

Тем не менее, вам все равно следует подумать об управлении идемпотентностью сообщений самостоятельно. Вы можете сделать это несколькими способами:

EventStore по умолчанию подавляет любые внешние транзакции при фиксации изменений в базе данных. Однако, если вы используете SQL Server или Raven, вы можете изменить TransactionScopeOption EventStore на Required, что должно гарантировать, что транзакция будет распространяться с использованием MSDTC, и все будет обработано за вас.

Альтернативой использованию 2PC может быть ведение журнала всех полученных сообщений и использование его для принятия/отклонения обработки конкретного сообщения. Пример такого подхода можно найти здесь: http://blog.jonathanoliver.com/2010/04/extending-nservicebus-avoiding-two-phase-commits/

person Elliot Ritchie    schedule 28.08.2011
comment
Спасибо, Эллиот. Я попробую это, когда вернусь в свой офис, но если я изменю подавление транзакций в EventStore, я ожидаю, что он будет писать только один раз (т.е. отправленный бит будет бесполезен и не нуждается в обновлении). Вы знаете что-нибудь об этом? - person Werner; 29.08.2011
comment
Очевидно, я не могу редактировать комментарий, но просто забуду свой вопрос. Делаю по вашей ссылке. Спасибо за быстрый ответ! - person Werner; 29.08.2011

Под капотом NES используется проект EventStore. По замыслу каждая фиксация не считается отправленной до тех пор, пока не будет вызвана функция MarkAsDispatched(). В результате я бы предположил, что что-то вызывает этот метод в неожиданном месте.

Прежде всего, у вас есть один запущенный экземпляр EventStore. Убедитесь, что у вас не запущено два экземпляра. Кроме того, я бы рекомендовал пройти через обработчик, чтобы узнать, в какой момент коммит помечен как отправленный.

person Jonathan Oliver    schedule 25.08.2011
comment
Привет, Джонатан! Я использую пример NES практически без изменений и не могу найти двойные экземпляры EventStore. Вы можете возразить, что репозиторий.Add() должен быть последней строкой в ​​моем обработчике NServiceBus, но почему-то неправильно, что порядок использования репозитория определяет, есть ли у нас несогласованность или нет. Но устраняет проблему. - person Werner; 26.08.2011