角色可以帮助我们对可变状态进行很好地隔离。尤其是当问题能够被拆分成可以独立运行的多个并发任务、并且并发任务彼此之间都是通过消息进行异步通信时,角色的表现更佳。但是,角色并未提供对跨任务的一致性进行管理的方法。所以如果我们希望两个或多个角色的动作要么全部成功、要么全部失败,则角色就无法独立实现,而此时我们就需要通过引入STM来与角色配合完成此类功能。在本节中,我假定你已经阅读过第6章、以及本章中有关角色和类型化角色的相关内容。
我们在4.6节和6.9节中曾经实现过一个用于在两个Account之间转账的AccountService类,该类可以作为我们理解角色和STM之间这种相互作用的绝佳示例。在这个示例中,存款和取款这两个动作对于单个账户来说都是隔离的,所以Account可以用一个简单的角色或一个类型化角色来实现。然而转账动作需要一对儿跨越两个账户的存取款动作配合起来才能完成。换句话说,在一个完整的转账过程中,由某个角色所负责的存款动作若想成功,只有当且仅当另一个角色所负责的取款动作也成功时才能达成。下面就让我们用角色和STM混搭的方式来实现这个转账示例。
Akka提供了一些混合使用角色和STM的选项。例如,我们可以创建一个独立的事务协调对象,并手动将多个角色按顺序摆放在事务中(关于这一层次的控制细节,请参阅Akka的帮助文档)。除此之外,我们还有两种用于管理角色间事务的方法可供选择。我们将会在下面两节分别来研究这两种方法:即如何使用transactors以及如何协调类型化角色。