User Tools

Site Tools


concepts:setbasedvalidation

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

concepts:setbasedvalidation [2013/03/13 18:05]
rtavassoli [Fehler in der Projektanlage]
concepts:setbasedvalidation [2013/03/13 18:53] (current)
rtavassoli
Line 20: Line 20:
   {   {
     // eigene Prüfungen     // eigene Prüfungen
-    var reservationNumber = registry.Register(Id, projectKey); // asynchron, wird also gespeichert+    var reservationNumber = registry.Reserve(Id, projectKey); // asynchron, wird also gespeichert
     ApplyChange(new ProjectKeySet(reservationNumber, projectKey);     ApplyChange(new ProjectKeySet(reservationNumber, projectKey);
   }   }
Line 78: Line 78:
 Jetzt können zwei Dinge passiert sein. Die SAGA hat den Befehl zur Bestätigung der Reservierung abgeschickt, ein VoidProjekt mit der Id=123 wurde erzeugt, und die Reservierung für {123,"ABC"} wurde storniert. In diesem Fall wird der neue Befehl mit einer DuplicateAggregateIdException abgelehnt und der Client muss den Befehl mit einer neuen Id absenden. Jetzt können zwei Dinge passiert sein. Die SAGA hat den Befehl zur Bestätigung der Reservierung abgeschickt, ein VoidProjekt mit der Id=123 wurde erzeugt, und die Reservierung für {123,"ABC"} wurde storniert. In diesem Fall wird der neue Befehl mit einer DuplicateAggregateIdException abgelehnt und der Client muss den Befehl mit einer neuen Id absenden.
 \\ \\ \\ \\
-Alternativ kann es sein, dass die SAGA noch nichts gemacht hat. In der erneuten Projektanlage wird nun wieder versucht, die Projektnummer "ABC" für die Id 123 zu reservieren. Die Registratur muss in diesem Fall eine ProjectKeyReservedException auslösen. Sie kann nicht davon ausgehen, dass sich das Projekt nach ganz bestimmten Regeln verhält. Es ist das Projekt, dass in diesem Fall weiß, dass da was nicht stimmen kann. Entweder gibt es wirklich ein anderes Projekt mit der Id, dass gerade eine Projektnummeränderung vornimmt, oder es gab für die Id einen Fehler, der noch nicht abgearbeitet ist. In beiden Fällen((Also bei der ProjectKeyReservedException)) sollte die Anlage mit einer neuen Id versucht werden.+Alternativ kann es sein, dass die SAGA noch nichts gemacht hat. In der erneuten Projektanlage wird nun wieder versucht, die Projektnummer "ABC" für die Id 123 zu reservieren. Die Registratur muss in diesem Fall eine PendingProjectKeyReservationException auslösen. Sie kann nicht davon ausgehen, dass sich das Projekt nach ganz bestimmten Regeln verhält. Es ist das Projekt, dass in diesem Fall weiß, dass da was nicht stimmen kann. Entweder gibt es wirklich ein anderes Projekt mit der Id, dass gerade eine Projektnummeränderung vornimmt, oder es gab für die Id einen Fehler, der noch nicht abgearbeitet ist. In beiden Fällen((Also bei der PendingProjectKeyReservationException)) sollte die Anlage mit einer neuen Id versucht werden.
 \\ \\ \\ \\
 Der einzige Fall, der nicht so einfach aufgelöst werden kann ist der, dass die neue Projektanlage abgeschickt wird, die alte Reservierung für die Projektnummer "ABC" noch nicht storniert wurde, und "ABC" im Zuge der Projektanlage nicht reserviert werden kann - obwohl "ABC" gleich freigegeben wird, was das Projekt aber nicht weiß. Die Projektanlage würde mit der Begründung abgelehnt werden, dass es die Projektnummer bereits gibt. Der einzige Fall, der nicht so einfach aufgelöst werden kann ist der, dass die neue Projektanlage abgeschickt wird, die alte Reservierung für die Projektnummer "ABC" noch nicht storniert wurde, und "ABC" im Zuge der Projektanlage nicht reserviert werden kann - obwohl "ABC" gleich freigegeben wird, was das Projekt aber nicht weiß. Die Projektanlage würde mit der Begründung abgelehnt werden, dass es die Projektnummer bereits gibt.
 \\ \\ \\ \\
-Dieser Fall kann aufgelöst werden, indem die Projektanlage bei einer ProjectKeyReservedException einfach immer wieder((Mit einer neuen Id - siehe ersten Fehlerfall)) versucht wird. Irgendwann ist die Reservierung weg, weil sie storniert oder bestätigt wurde.+Dieser Fall kann aufgelöst werden, indem die Projektanlage bei einer PendingProjectKeyReservationException einfach immer wieder((Mit einer neuen Id - siehe ersten Fehlerfall)) versucht wird. Irgendwann ist die Reservierung weg, weil sie storniert oder bestätigt wurde.
 \\ \\ \\ \\
 So, das sollte alle Fälle abdecken. Zusammengefasst: So, das sollte alle Fälle abdecken. Zusammengefasst:
-> Wenn man in der Projektanlage die Projektnummer setzen möchte und eine DuplicateAggregateIdException oder eine ProjectKeyReservedException erhält, wiederholt man die Anlage einfach immer wieder bis sie klappt oder eine andere Fehlermeldung erhält((Die Projektnummer kann dafür z.B. bei einem Import als idempotency-Id genutzt werden, denn wenn die Anlage funktioniert hat samt Projektnummernvergabe, würde man bei einem erneuten Versuch eine DuplicateProjectKeyException erhalten)). Man kann aber auch bei einer DuplicateAggregateIdException prüfen, ob es das Projekt überhaupt gibt, und wenn ja, ob es ein VoidProject ist. Dito für die andere Exception. +> Wenn man in der Projektanlage die Projektnummer setzen möchte und eine DuplicateAggregateIdException oder eine PendingProjectKeyReservationException erhält, wiederholt man die Anlage einfach immer wieder bis sie klappt oder eine andere Fehlermeldung erhält((Die Projektnummer kann dafür z.B. bei einem Import als idempotency-Id genutzt werden, denn wenn die Anlage funktioniert hat samt Projektnummernvergabe, würde man bei einem erneuten Versuch eine DuplicateProjectKeyException erhalten)). Man kann aber auch bei einer DuplicateAggregateIdException prüfen, ob es das Projekt überhaupt gibt, und wenn ja, ob es ein VoidProject ist. Dito für die andere Exception. 
-> Wenn man für ein vorhandenes Projekt die Projektnummer setzen möchte, kann es genauso passieren, dass die Reservierung klappt, das Speichern des Projektes aber nicht. In diesem Fall wird ja das Projekt von der SAGA regelmäßig abgefragt. In diesem Fall kann der Befehl zur Projektnummernänderung bei einer ProjectKeyReservedException einfach so lange abgeschickt werden, bis der Befehl funktioniert oder aus dem Fehler eine zur ProjectKeyRegisteredException geworden ist.+ 
 +> Wenn man für ein vorhandenes Projekt die Projektnummer setzen möchte, kann es genauso passieren, dass die Reservierung klappt, das Speichern des Projektes aber nicht. In diesem Fall wird ja das Projekt von der SAGA regelmäßig abgefragt. In diesem Fall kann der Befehl zur Projektnummernänderung bei einer PendingProjectKeyReservationException einfach so lange abgeschickt werden, bis der Befehl funktioniert oder aus dem Fehler eine ProjectKeyRegisteredException geworden ist
 +===== Alternativlösung ===== 
 +Damit der Client eine Projektanlage nicht immer wieder mit einer neuen Id senden muss, kann das Projekt und der Command Handler ein wenig angepasst werden. Der Command Handler kann wie folgt aussehen: 
 +<code csharp> 
 +  public ProjectCommandHandler: CommandHandler, Handles<AddProject> 
 +  { 
 +    public void Handle(AddProject message) 
 +    { 
 +      var repo = new Repository<Project>(); 
 +      var proj = repo.Get(message.Id); 
 +      if (proj == null) 
 +      { 
 +        proj = ProjectFactory.AddBootstrapped(message.Id); 
 +        repo.Save(proj);  // das Projekt ist nun vorhanden! auch wenn es hiernach nicht mehr weiter geht. 
 +      } 
 +      proj.Bootstrap(message.ProjectName, message.ProjectKey, ...); 
 +      repo.Save(proj); 
 +    } 
 +  } 
 +</code> 
 +Das sieht merkwürdig aus. Jetzt kann der Client bei einer PendingProjectKeyReservationException den Befehl einfach neu senden, muss die Id des Projektes nicht ändern. Ein Projekt, dass mit AddBootstrapped erzeugt wurde, ist im Read Model nicht sichtbar, wird auch nur zwei Befehle akzeptieren: 
 +  * Bootstrap 
 +  * ConfirmProjectKeyReservation 
 +Bootstrap ist wie eine Factory, und wird vom Projekt nur akzeptiert, solange es den Status //Bootstrapping// hat. ConfirmProjectKeyReservation wird im //Bootstrapping// Status immer ReservedProjectKeyNotUsed veröffentlichen. Wenn ein Projekt also zum Bootstrapping angelegt werden konnte, in der Bootstrap() Methode eine Projektnummer reserviert hat, danach aber ein Fehler passiert ist, kann die Bootstrap() Methode immer wieder aufgerufen werden, genau wie SetProjectKey() in einem vorhandenen Projekt. 
 +\\ \\ 
 +Es besteht jetzt nur noch die //Gefahr//, dass bei Fehlern nach der Reservierung, oder bei Änderungen an der Projektnummer schnell hintereinander, die Reservierung noch besteht aber weder storniert noch bestätigt wurde. Das System erhält dann eine PendingProjectKeyReservationException von der Registratur. Die Command Handler können den Aufruf in dem Fall einfach immer wieder behandeln, denn sie wissen, dass dieser Fehler schließlich verschwinden muss. 
 +\\ \\ 
 +Sie sollten dabei ein Time-Out setzten, d.h. dass der Befehl letztendlich abgelehnt wird, wenn der Fehler z.B. nicht nach 30 Sekunden verschwindet. In dem Fall gibt es Probleme im System, die das Messaging daran hindern, Nachrichten rechtzeitig //an den Mann// zu bringen.
concepts/setbasedvalidation.1363194334.txt.gz · Last modified: 2013/03/13 18:05 by rtavassoli