您的问题的解决方案是DBIO 组合。
首先,您所有的原子操作都应该由 a 实现DBIOAction
(ADBIOAction
表示将在 DB 上执行的操作)。
接下来,您可以将所有 DBIOAction 组合在一起,使用andThen
、flatMap
或使用 a for comprehension
(请参阅DBIOAction api)
当您拥有组合的 DBIO 时,您可以调用.transactionally
以使 DBIOAction 在数据库上执行时具有事务性。
样本:
def updateUsername(id: Long, username: String) = Schemas.users.filter(_.id === id).map(_.username).update(username)
def updateUserAddress(id: Long, address: String) = Schemas.addresses.filter(_.id === id).map(_.address).update(address)
def getUser(id: Long) = Schemas.users.filter(_.id === id).head
val operations = for {
_ <- updateUserName(1, "foo")
_ <- updateUserAddress(1, "bar")
user <- getUser(1)
} yield user
db.run(operations.transactionally)
获取db
对象的方法在 Play 文档中有说明。