Scala 异步数据库调用

Scala Asynchronous Database Calls

我目前正在使用 Slick 3.x.x,它对数据库的所有调用都是完全异步的。比方说,我有一个具有某种版本控制的 table。每次我从一个已经存在的条目创建一个新条目(即更新一个给定的条目)时,我必须确保我增加了版本号。

如何确保在这个异步的数据库通信世界中我可以保持数据完整性?在我的版本控制案例中,我首先会为最大版本执行 select,这会返回一个 Future,然后我使用这个 Future 的结果,递增 1 并发出创建命令!

很可能线程 1 以 select 最大版本启动并暂停了一段时间,线程 2 迎合新请求可能 运行 select 最大版本并递增并将新记录写入数据库。现在 thread1 返回并尝试执行相同的进程,但结果是 thread1 会覆盖 thread2 在数据库中写入的内容。

可能我最终会得到多个重复项,因为多个 future 的顺序 运行 可能不同!

应用程序管理其与数据库交互的异步性不会改变数据库事务的语义。如果您想要原子的、一致的操作序列,那么您需要一个数据库事务。 Slick offers 一个名为 transactionally 的 "combinator",它将在数据库事务中强制执行一系列操作 运行。