在数据库中刷新对象之前的平滑更新操作 returns
Slick update operation returns before object is flushed in the database
我遇到这样一种情况,当我在更新对象后立即获取它时,有时我从数据库中获得的结果不包含最新的更改。
这让我认为更新线程 returns 在对象实际提交到数据库之前。这是预期的行为吗?
我认为更新方法只会 return 在更改成功刷新到数据库之后,但看起来这不能保证。
下面是演示我在说什么的伪代码。
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
}
下面是我的 update
逻辑
def update(myObject: MyObject): Future[Int] = {
db.run(table.filter(_.id === myObject.id).update(myObject))
}
问题是您没有考虑 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
}
因为 for-comprehension 中的 <-
是 flatMap
的语法糖
我遇到这样一种情况,当我在更新对象后立即获取它时,有时我从数据库中获得的结果不包含最新的更改。
这让我认为更新线程 returns 在对象实际提交到数据库之前。这是预期的行为吗?
我认为更新方法只会 return 在更改成功刷新到数据库之后,但看起来这不能保证。
下面是演示我在说什么的伪代码。
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
}
下面是我的 update
逻辑
def update(myObject: MyObject): Future[Int] = {
db.run(table.filter(_.id === myObject.id).update(myObject))
}
问题是您没有考虑 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
}
因为 for-comprehension 中的 <-
是 flatMap