401279 (2) [Avatar] Offline
#1
Hi again,

I have a question regarding composition of commands in a monadic way and error handling.

Let's consider this piece of code from chapter 8:
def transfer(from: String, to: String, amount: Amount): Command[Unit] = 
  for {
    _ <- debit(from, amount)
    _ <- credit(to, amount)
  } yield ()

which creates a new command by composing two other commands.

My question is about what happen when the second command, credit(to, amount), fails. From what I understand (which get confirmed with soe tests), the result is the following:
- The composed command (transfer) fails
- but the first composing command (debit(from, amount)) get executed as it happens before the failure

If this correct in terms of monadic programing logic, it is not very intuitive from a domain point of view. What I would expect in a banking context is that no command get executed if the whole failed: if we do a transfer and the credit operation fails, the debit operation that follows should not occur.

Am I correct or did I miss something?

And if I am correct, do you have some suggestion on how to obtain such a behavior, that is to have monadicly-composed commands that get validated as a whole before being executed?
From what I understand, I would say that this requires to implement some sort of session-commit-rollback mechanism at the interpreter level...

Best regards,
Marc-Antoine
Debasish Ghosh (116) [Avatar] Offline
#2
The code fragment illustrates monadic composition and not transaction handling. Typically if you want to ensure atomic execution then you need to execute the whole sequence of monadic statements within a transaction. You need a separate combinator to handle transactions. e.g. if you use Slick then you can use something like the following ..

def transfer(from: String, to: String,&nbsp;amount: Amount): Command[Unit] = 
  (for {
    _ <- debit(from, amount)
    _ <- credit(to, amount)
} yield ()).transactionally


where the transactionally combinator will ensure database level atomicity of operations.

HTH.