July 05 21:59~23:12
▲Figure 1: Behavior is uncontrollable
The last episode discussed the topic of event versioning, this episode will discuss Behavior Versioning. This problem Teddy also read Gregory Young’s ” Versioning in an Event Sourced System ” and found that if he did not notice the “behavioral version” of the program, in the Event Sourcing system, the system may be changed due to program revision (domain events remain unchanged). Status error.
Gregory Young’s book ” Versioning in an Event Sourced System ” has a very simple example to illustrate behavioral version control, and there are similar but more complex examples in ezKanban, where Teddy directly borrows Gregory Young’s example. As shown in Figure 2, there is a sell() method on the POS Aggregate of the sales system, which applies an event in the ItemSold field, where the last parameter of the event is the subtotal of the sales amount.
▲Figure 2: sell method
Figure 3 is the ItemSeld’s event handler, which takes the subTotal from the domain event and multiplies it by 0.08 to calculate the sales tax (tax is an attribute on the POS); it looks fine to program it this way.
▲Figure 3: Calculate taxes, version 1.0 program
One day the government raised the sales tax from 8% to 10%, so you changed the program to Figure 3. Now here comes the problem, when you reload the POS, it will replay all events, and then suppose there is an item with subTotal of 100, and the tax calculated by the version 1.0 program is 8. But after the revision of the program, the tax calculated by the version 2.0 program has become 10. However, at the time of this transaction, the sales tax was still 8%, so there should not be a situation of “tampering with history” due to the change of the code.
▲Figure 3: Calculate tax, version 2.0 program
As shown in Figure 4, the solution is actually very simple, that is to calculate the tax and consider it as part of the content of the domain event, and that’s it. Returning to the original definition of the domain event: “representing a system state change”, so the content of the domain event should “at least” store “all data that can represent this state change.” In this example, the “tax rate” will change over time , and therefore affects the amount of tax. Therefore, the ItemSold field event should include the calculated tax, or only include the taxRate (tax rate) and then calculate the tax based on this taxRate.
▲Figure 4: The modified version will not be adjusted by the program behavior to change the aggregation state
The above example is simple. In some cases, if Aggregate calls external services, it is likely to cause behavior version control problems, thus making it impossible to replay domain events to reproduce the system state. For example, when requesting payment from a third-party cash flow API, if an event in the replay field will result in repeated payment? These are the details to pay attention to. The solution to calling an external service that causes the program’s behavior to become nondeterministic during replay is similar to the tax calculation example above, calling the external service when the domain event is generated, and storing the return value of the external service on the domain event. This allows for deterministic replay. All in all, the point is that all the data needed to rebuild the system state should be stored in the event stream, so that the same result will appear every time you replay, as shown in Figure 5.
▲Figure 5: Store the return result of the external service in the domain event
Gregory Young also mentioned more details about behavioral version control in the book ” Versioning in an Event Sourced System “, for those who are interested, please refer to it by yourself.
next episode preview
In this series of articles, Teddy uses EventStoreDB with PostgreSQL as the Event Store. Many early adopters of Event Sourcing used Apache Kafka as the Event Store. The next episode will talk about whether it is appropriate to use Apache Kafka as an event store?
Yuzo’s inner monologue: Reconstructing the crime scene is really not that simple.
This article is reprinted from https://teddy-chen-tw.blogspot.com/2022/07/14.html
This site is for inclusion only, and the copyright belongs to the original author.