Паралелност при създаване с CQRS и EventStore

Основна информация: Използвам външен доставчик на OAuth за влизане. Ако потребителят влезе във външния OAuth, той може да влезе в моята система. Този потребител обаче може все още да не съществува в моята система. Всъщност не е технологичен проблем, но използвам JOliver EventStore за това, което си струва.

Логика:

  1. Не ми е дадено ръководство за нови потребители. Просто имам имейл адрес.
  2. Проверявам моя модел за четене, преди да изпратя команда, ако имейлът на потребителя съществува, издавам команда за влизане с идентификатора, ако не, издавам команда CreateUser с генериран идентификатор. Проблемът ми е в случай на нов потребител.
  3. Възниква запис в хранилището на събития с новия идентификатор.

Проблем: Да предположим, че по някакъв начин са издадени две команди за създаване, преди моделът за четене да бъде актуализиран поради опресняване на браузъра или някаква друга аномалия, която възниква, преди да се постигне съгласуваност с модела за четене. Всичко е наред, това не е мой проблем.

Какво се случва: Тъй като новият идентификатор е гребен на Guid, няма шанс хранилището на събития да знае, че тези две команди CreateUser представляват един и същ потребител. Докато стигнат до модела за четене, моделът за четене ще знае (защото имат един и същ имейл) и може да обедини двата записа или да предприеме някакво друго компенсиращо действие. Но сега моят модел за четене не е синхронизиран с магазина за събития, който все още смята, че това са две отделни единици.

Може би няма значение, защото:

  1. Повторното възпроизвеждане на събитията ще има същия ефект върху прочетения модел, така че трябва да е ОК.
  2. Тъй като и двете команди са дублиращи се команди за създаване, те трябва да съдържат идентична информация, така че не е като да губя нещо в хранилището на събития.

Може ли някой да осветли как са се справили с подобни проблеми? Ако трябва да се извърши някакво компенсиращо действие, услугата за четене на модел издава ли някаква команда за компенсация, когато осъзнае, че има дублиран запис? Има ли по-проста методология, която не обмислям?


person swannee    schedule 29.06.2012    source източник


Отговори (1)


Вие сте много близо до това, което смятам за подходящо възможно решение. Сценарият, ако мога да обобщя, е донякъде такъв:

  • Извършете OAuth-entication.
  • Използвайки модела за четене, решавайте между повтарящ се и нов посетител въз основа на имейл адреса.
  • В случай на нов посетител, изпратете командно съобщение RegisterNewVisitor, което се обработва и съхранява в магазина за събития.
  • Да приемем, че има някаква паралелност, която за един и същ имейл адрес предизвиква две съобщения RegisterNewVisitor, всяко от които съдържа това, което системата смята за ключа, свързан с имейл адреса. Тези ключове (водачи) са различни.
  • Открийте този проблем с дублиран ключ в модела за четене и обединете записите на двата модела за четене в един запис.

Сега вместо да обедините записите в модела за четене, защо не изпратите ResolveDuplicateVisitorEmailAddress { Key1, Key2 } към вашия модел на домейн, оставяйки на модела на домейн (кодифицираната форма на бизнес решението, което трябва да се вземе) да разреши този проблем. Можете дори да имате специален модел за четене, който да се справя с този вид проблеми, другият модел за четене просто ще получи нещо като събитие DuplicateVisitorEmailAddressResolved и ще го проектира в правилните записи.

Предупреждение: Вие зададохте технически въпрос и аз ви дадох техническо, възможно решение. По принцип не бих приложил тази техника, освен ако нямам някакъв бизнес индикатор, че си струва да инвестирам (каква е честотата на влизане на потребител едновременно за първи път - може би решаването на проблема по този начин е просто начин за игнориране на основната причина (flakey OAuth, няма въведен процес за регистриране на нов посетител и т.н.)). Има и други технически решения на този проблем, но аз исках да ви дам най-близкото до това, което вече имате. Те варират от последователно регистриране на нови посетители до поддържане на проекция в паметта на посетителите, които все още не са в прочетения модел.

person Yves Reynhout    schedule 30.06.2012
comment
Искам да кажа, че това е решение, което принадлежи към модела на домейна, ако следвате този курс на действие. - person Yves Reynhout; 30.06.2012
comment
За да бъде пълно - това е обсъждано многократно - codebetter.com/gregyoung/2010/08/12/ - person Yves Reynhout; 01.07.2012
comment
Добре отговорено, благодаря за знанията по темата. Сигурен съм, че това е отговаряно много пъти, но с CQRS като цяло е трудно да се намерят окончателни отговори, тъй като те са толкова разпръснати. Също така съм съгласен, че може да усложнявам прекалено ситуация, когато това всъщност няма значение. Може да не е необходимо да правя нищо в този случай, но самият случай повдигна по-скоро въпрос за подход в ситуации, в които трябва да разреша това. Благодаря за отговора и линка също. - person swannee; 02.07.2012