Scala Slick update操作在数据库中刷新对象之前返回

Scala Slick update操作在数据库中刷新对象之前返回,scala,asynchronous,playframework,slick,Scala,Asynchronous,Playframework,Slick,我遇到了这样一种情况:当我在更新对象后立即获取对象时,有时从DB获得的结果不包含最新的更改 这使我认为更新线程在对象实际提交到数据库之前返回。这是预期的行为吗 我认为update方法只有在成功地将更改刷新到DB之后才会返回,但是看起来这并不能保证 下面是演示我所说内容的伪代码 def processObject = { for { objectId: Option[Long] <- saveObjectInDb _ <- { //perform oth

我遇到了这样一种情况:当我在更新对象后立即获取对象时,有时从DB获得的结果不包含最新的更改

这使我认为更新线程在对象实际提交到数据库之前返回。这是预期的行为吗

我认为update方法只有在成功地将更改刷新到DB之后才会返回,但是看起来这并不能保证

下面是演示我所说内容的伪代码

def processObject = {
  for {
    objectId: Option[Long] <- saveObjectInDb

    _ <- {
     //perform other synchronous business logic and then update created object details
      dao.findById(objectId.get).map { objectOption: Option[MyObject] =>
        dao.update(objectOption.get.copy(processingStep = "third-step"))
      }
    }

    mostRecentMyObject <- dao.findById(objectId.get)
  } yield mostRecentMyObject
}

问题是您没有考虑
更新
方法返回的内部
未来

给定
findById
的签名:

def findById(id: Long): Future[Option[MyObject]]
片段:

dao.findById(objectId.get).map { objectOption: Option[MyObject] =>
  dao.update(objectOption.get.copy(processingStep = "third-step"))
}
将提供一个类型为
Future[Future[Int]]
的对象

您应该在
findById
未来使用
flatMap
而不是
map
,如下所示:

dao.findById(objectId.get).flatMap { objectOption: Option[MyObject] =>
  dao.update(objectOption.get.copy(processingStep = "third-step"))
}
这将简化为一个未来(
future[Int]
),因此您可以确保仅在插入对象后检索该对象

此外,您可以将其改写为:

def processObject = {
  for {
    objectId: Option[Long] <- saveObjectInDb

    objectOption <- dao.findById(objectId.get)

    _ <- dao.update(objectOption.get.copy(processingStep = "third-step"))

    mostRecentMyObject <- dao.findById(objectId.get)
  } yield mostRecentMyObject
}
def processObject={
为了{

objectId:Option[Long]问题在于您没有考虑
update
方法返回的内部
Future

给定
findById
的签名:

def findById(id: Long): Future[Option[MyObject]]
片段:

dao.findById(objectId.get).map { objectOption: Option[MyObject] =>
  dao.update(objectOption.get.copy(processingStep = "third-step"))
}
将提供一个类型为
Future[Future[Int]]
的对象

您应该在
findById
未来使用
flatMap
而不是
map
,如下所示:

dao.findById(objectId.get).flatMap { objectOption: Option[MyObject] =>
  dao.update(objectOption.get.copy(processingStep = "third-step"))
}
这将简化为一个未来(
future[Int]
),因此您可以确保仅在插入对象后检索该对象

此外,您可以将其改写为:

def processObject = {
  for {
    objectId: Option[Long] <- saveObjectInDb

    objectOption <- dao.findById(objectId.get)

    _ <- dao.update(objectOption.get.copy(processingStep = "third-step"))

    mostRecentMyObject <- dao.findById(objectId.get)
  } yield mostRecentMyObject
}
def processObject={
为了{

objectId:选项[长]感谢Luca,我确实能够使用
flatMap
修复问题。起初我不愿意使用该修复程序,因为它看起来像是在掩盖一个重大问题。感谢Luca,我确实能够使用
flatMap
修复问题。起初我不愿意使用该修复程序,因为它看起来像sw把一个重大问题隐藏起来。