Transactional Effects in Scala
Composing effects with rollbacks in case of failure
Join the DZone community and get the full member experience.Join For Free
This post was inspired by a StackOverflow answer for the question Compose Futures with Recovery in Scala: Is it possible to compose
Futures in a manner where, if one of them fails, a previous
Future's execution result will be rolled back via some function?
The case with
Future can be generalized to some effect
F[_], so we can say: How can we compose effects
F[_] in a manner where, if one of them fails, the previous
F[_] execution result will be rolled back via some function? This behavior is similar to what we know as a Transaction.
For the code solution below
2.3.1 used. The final solution can look like this:
And small demo:
Which will print out the next output (made shorter for the sake of the example):
A executed B executed B recovered A recovered java.lang.Exception: C failed
Also, you can play with demo in Scatie: https://scastie.scala-lang.org/W8qmBrVQRx6izAVo3Q9yvg
If an application is written in the pure Functional Programming paradigm, ideally it should not have any side effects that it needs to "roll-back" in case of another effect failure. But this approach can be useful when, for instance, the app stores documents in more than one database, e.g. Mongo and Elasticsearch, and removes the document from the main MongoDB if storing in Elasticsearch failed.
Thank you for your attention and hope it will be helpful!
Published at DZone with permission of Ivan Kurchenko. See the original article here.
Opinions expressed by DZone contributors are their own.