scala - 从 Squeryl 迁移时使用 Slick 3.0 事务
问题描述
我正在将一些 Scala 代码从 Squeryl 迁移到 Slick。一切都很顺利,直到我碰到交易的话题。Squeryl 使处理事务变得非常简单:您只需将代码(无论是否与 DB 相关)包装在一个transaction
块中即可。
从我可以在网上收集的示例来看,似乎人们希望重新构建整个项目,使其能够很好地使用它的一元方法和理解,这是我真的想避免的事情。
考虑任意一段代码,例如:
def f(): Unit = {
UserRepository.getUser()
... some imperative code
ServiceRepository.getServer()
...
ServerRepository.updateServer(...)
...
UserRepository.insertNewUser(...)
}
有没有一种方法可以轻松地将其包装在某种事务块中,而无需更改方法的内部逻辑?
解决方案
有没有一种方法可以轻松地将其包装在某种事务块中,而无需更改方法的内部逻辑?
简短的回答是否定的,但这取决于那些调用UserRepository
和其他方法返回的内容:
如果它们是
Future[T]
(或者如果您已阻止从未来获取值),则您已经运行了查询,所以这是一个否,因为您在 Slick 层之外。如果它们是动作 (
DBIO
) 甚至是查询,那么它可能不会改变内部逻辑:您必须将动作组合在一起,但可以通过混合任意代码来实现。例如,flatMap
(或理解)将允许这样做。
作为混合逻辑和组合动作的示例,您可以编写以下代码:
val action = for {
user <- UserRepository.getUser // a DBIO[User]
result <- if user.notPermitted() {
DBIO.failed(new IOException("Not allowed")
} else {
DBIO.successful(user)
}
} yield result
DBIO
介绍在(可能使用successful
and )方面起作用的方法和值failed
可能会使这种转换对您来说不那么痛苦。有一个答案可能会为混合逻辑和操作提供更多想法:https ://stackoverflow.com/a/31490020/154248
您必须执行最终的组合操作,.transcationally
以确保它们的所有操作都在事务中运行。这在:https ://scala-slick.org/doc/3.3.2/dbio.html#transactions
想到了另外两种可能性:
可以想象,您可以为 Slick 实现自己的后端。但这似乎需要做很多工作,而且你会一直与 Slick 其余部分的想法作斗争。
虽然我通常不建议这样做,但旧版本的 Slick(Slick 2)似乎更接近 SQueryl:https ://scala-slick.org/doc/2.1.0/connection.html#session-handling ...和这可能会为您提供通往 Slick 的垫脚石,然后作为单独的工作线进入 Slick 3。
推荐阅读
- python - 访问 cookie 文件并将其上传到 selenium webdriver
- firebase - 无法将 TXT 记录添加到 Firebase DNS 域
- postgresql - 在 Pl/pgSQL 中使用 FOR 循环时,它在 Postgres 11.8 中不起作用
- jquery - 使用 jQuery 从购物车中添加商品和删除商品。我无法删除仅使用 jQuery 添加的项目。script.js 文件中的方法一
- vue.js - 如果组件在 Nativescript Vue 中处于非活动状态,如何停止代码执行
- asp.net - 无法使用 ftp 从 asp.net 删除服务器上的文件
- c++ - ORA-06550:第 1 行,第 7 列:PLS-00306:调用“输入”时参数的数量或类型错误
- excel - 如果没有公式或手动覆盖,单元格颜色会发生变化
- git - Github:当特定分支合并到主分支时,我如何通知松弛?
- oop - 从其他类调用方法