-
Notifications
You must be signed in to change notification settings - Fork 491
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Not completed logic which needs transaction. #48
Comments
Hey @timsolov! Thanks, it's great to hear the project is helpful. 🙂 What you mention is correct, these two places don't have consistent updates. We did this on purpose to show how to refactor it later, but didn't come to this stage yet. The short answer is, keep things you want to be atomic in a single transaction. So definitely in a single service, where you have control over it. Another approach is using event-driven patterns: saving one entity in one of the services, and asynchronously updating the other one. In this case, you have to be able to accept eventual consistency. If your application is just a single service it should be possible to keep database updates within transactions where applicable. Sadly this won't work for external calls — events work great for these. I've described one approach in this example: https://github.com/ThreeDotsLabs/watermill/tree/master/_examples/real-world-examples/transactional-events |
Hi! Thank you for your work, your articles are really cool and useful! The updateFn approach is awesome, but I'm not sure how to apply it across entities. I'm having difficulty putting 2 tables into one transaction. I'll give you an example. I need to implement Is it generally correct to use this approach for multiple tables? |
Hey @wintermonth2298! This is a common question about this pattern, and the reason usually is thinking about the business entities as SQL tables and modeling the code around them. But they don't need to map 1:1, and bigger entities (aggregates) can easily span multiple tables. I've described it in this article: https://threedots.tech/post/common-anti-patterns-in-go-web-applications/#starting-with-the-database-schema The point is there's no rule that You can consider having a regular product, err := productsRepo.ByID(productID)
err := customerRepo.Update(ctx, func(customer *Customer) error {
customer.BuyProduct(product)
return nil
}) Or, consider a dedicated method like I hope this helps! As always, the context matters, and I don't know your domain well enough. |
Thank you for your repo and articles. This is awesome work!
I'm trying to rewrite my legacy service to the yours approach.
And I have a question:
How to guarantee that all hours in this command will be updated atomic?
wild-workouts-go-ddd-example/internal/trainer/app/command/make_hours_available.go
Line 24 in 33e3c49
Or what will happen when repo will be updated here:
https://github.com/ThreeDotsLabs/wild-workouts-go-ddd-example/blob/master/internal/trainings/app/command/schedule_training.go#L56
but one of external service won't be available? Will we have incompleteness here?
The text was updated successfully, but these errors were encountered: