3.2 KiB
Optimistic (first or last one wins)
Pessimistic (first person locks it)
Realistic - what we want is something that is able to lock things for the right amount of granularity. One difficulty: multi-table spanning transactions. Databases support MVCC (multi version concurrency control). If you turn this on, expect to see exceptions in your logs. This is a clue that you have some collaboration going on! You might be able to redesign your business logic to solve your collaboration issues. Therefore, traditional entity-relationship models are dangerous (you'll be operating on more than one entity at a time). How to get to realistic concurrency?
As part of transactions, you get one single domain object. You call methods to update its state. If successful, it updates its own state. This applies to entities that can be operated on outside of a single transaction. This is a simple rule, but very difficult to follow. However, it is much easier to follow if you have split things up into good service boundaries. Some changes can be concurrent, others can't (?). Good: you change the customer's address, I update the customers credit history.
Bad: You cancel an order, I ship an order. We have a race condition. You're in a collaborative domain. The rules of CQRS applies. Commands are almost never supposed to fail. This leads us to deeper business analysis. Fundamentally: race conditions don't actually exist in the business domain! Use cases and business processes are always expressed by business domain experts in sequential form. Most of the time, we find a race condition, it is the result of a work around. We need to dig deeper and find out what the race condition was originally trying to solve. Example, we don't want allow them to ship canceled orders and they can't cancel shipped orders. Any time it's not immediately apparent how the company is going to make money or save money, you don't understand the business model completely. Try business analysis: 5 whys. You're supposed to listen! Ask for the business process to be explained to us as if we were a five year old.
-
Cannot cancel shipped orders
-
Why? because shipping costs money
-
So? that money would be lost if the customer canceled
-
Why? we refund orders immediately
-
Analyze:
- when an order is canceled, does the refund need to be given immediately? => no
- can we give a partial refund? => yes
-
Result: now we can get rid of the one if-statement to check if the order is shipped before we cancel
-
Other analysis
- Most orders are canceled quickly after being made => it's not equally likely that an order will be canceled at any time after the order was made
- So...wait until the high-probability period is past to actually begin the shipping process
-
-
Cannot ship canceled orders One conclusion! Domain Models are SAGAS! Business people like to talk about business policies. Refund policies, insurance policies. Sags are a really good way to implement policies. They have that time component to it that allows us to model domain concepts well. "In two weeks you will qualify for this". "You can cancel for free within the first day of your order".