Play 2.4 中的 Slick 3.0 事务

Posted

技术标签:

【中文标题】Play 2.4 中的 Slick 3.0 事务【英文标题】:Slick 3.0 transactions in Play 2.4 【发布时间】:2015-08-28 01:29:46 【问题描述】:

我有一个控制器,它对数据库模型类进行各种调用,这些类在 PostgreSQL 数据库上执行各种操作。我想在单个事务中执行所有这些操作。在 Play 2.3 中,我能够将代码包装在 DB.withTransaction ... 中,以使其在单个事务中执行所有操作。

在 Play 2.4 和 Slick 3.0 中,似乎 Slick 处理连接管理,DB.withTransaction 似乎不再是处理此问题的正确方法(它抛出 IllegalArgumentException 并显示消息“无论如何都找不到默认数据库”)。从控制器内部对事务中的 Slick 操作进行分组的正确方法是什么?

【问题讨论】:

【参考方案1】:

您的问题的解决方案是DBIO composition。

首先,您的所有原子操作都应由DBIOAction 实现(DBIOAction 表示将在数据库上执行的操作)。

接下来,您可以使用andThenflatMap 或使用for comprehension 将所有DBIOAction 组合在一起(请参阅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文档中有说明。

【讨论】:

以上是关于Play 2.4 中的 Slick 3.0 事务的主要内容,如果未能解决你的问题,请参考以下文章

使用 Slick 3.0 在同一事务中进行多次插入

删除不适用于 Play! 2.4、Slick 3 和 PostgreSQL

如何使用Slick和Play在测试中应用手动演变! 2.4

升级 Play 到 2.4,Slick 到 3.1.1,值 withTransaction 不是 play.api.db.slick.Database 的成员

无法使用 play-slick 1.0.1/slick 3.0 连接到 mysql 数据库:配置错误

在 Play framework 2.4 中使用 Slick 3 在哪里初始化数据库?