
CHAPTER 6 ■ ACTORS AND CONCURRENCY
163
And get the current balance for both the Actors. Note that the second balance is not
used, but the result indicates that we’re in the transaction for both the Actors.
(src !? (500, (xid, GetInfo)), dest !? (500, (xid, GetInfo))) match {
case (Some(Info(sbal)), Some(Info(dbal))) =>
We’re going to create the destination account before debiting the source account. This
will demonstrate that rolling back the transaction works correctly.
dest ! (xid, Update(dact, v => (v getOrElse 0) + amount))
if (sbal.getOrElse(sact, 0) > amount) {
src ! (xid, Update(sact, v => (v getOrElse 0) - amount))
src ! (xid, CommitXAction)
dest ! (xid, CommitXAction)
} else {
src ! (xid, RollbackXAction)
dest ! (xid, RollbackXAction)
}
case _ =>
src ! (xid, RollbackXAction)
dest ! (xid, RollbackXAction)
}
}
We’ve defined the ability to transactionally transfer money between accounts on two
different Actors. Let’s see whether it works. Let’s transfer $700 from
dpp to archer:
transfer2(dpp, "Checking", archer, "Checking", 700)
println("XFer 700 dpp -> archer:")
println("dpp: "+(dpp !? GetInfo))
println("archer: "+(archer !? GetInfo))
What does the console say?
XFer 700 dpp -> archer:
dpp: Info(Map(Savings -> 300, Checking -> 100))
archer: Info(Map(Savings -> 2000, Checking -> 750))
Yes, it works correctly. What happens if we try the transfer again?
transfer2(dpp, "Checking", archer, "Checking", 700)
println("Again, XFer 700 dpp -> archer:")
println("dpp: "+(dpp !? GetInfo))
println("archer: "+(archer !? GetInfo))
19897ch06.fm Page 163 Monday, April 20, 2009 11:10 AM