![](/img/trans.png)
[英]Does using 'create index concurrently' in postgres, help future rows which will be inserted to be free from locks?
[英]Future returned by Slick run method completes successfully before rows have been inserted
我正在使用 Slick 和 PostgreSQL 進行存儲的 Scala 應用程序。 我有一個方法foo
從一個 CSV 文件中讀取數據並將大約 10,000 行插入到數據庫中。 在行插入操作的 Future 完成后,另一個方法bar
被調用,它從數據庫中檢索這些行並對它們執行一些操作。 這就是問題所在:實際上沒有從數據庫中檢索行,因為在 Future 完成時沒有插入任何行。
從我在尋找答案和官方文檔時可以收集到的信息來看,在成功執行插入語句之前,未來不應該完成。 如果我將以下代碼Thread.sleep(30000)
到bar
,允許首先執行 insert 語句,則這些方法會提供預期的結果。 現在,出於顯而易見的原因,我寧願不這樣做,所以我正在尋找替代方案。
下圖說明了調用初始方法doStuff
的程序流程:
doStuff
在返回 Future 之前調用foo
加載數據並將其存儲在數據庫中。 然后在doStuff
映射此 Future 並調用bar
。 bar
bar 從數據庫中檢索行並處理它們。 但是,由於在調用bar
的位置沒有插入任何行,因此不會處理任何數據。
doStuff
方法:
def doStuff(csvFile: File): Future[Unit] = {
fooService.foo(csvFile)
.map(_ => {
csvFile.delete()
barService.bar()
})
}
foo
方法:
def foo(file: File) Future[Unit] = {
val reader = CSVReader.open(file)
fooStorage.truncateFooData().map(_ => {
val foos = for (line <- reader.iterator if
line.head != "bad1" &&
line.head !="bad2")
yield parseFooData(line)
fooStorage.saveFooDataBulk(foos.toSeq)
})
}
我如何使用 Slick 插入行:
override def saveFooDataBulk(fooSeq: Seq[Foo]): Future[Seq[Foo]] =
db.run(DBIO.seq(fooQuery ++= fooSeq)).map(_ => fooSeq)
我希望在所有行都插入數據庫后調用bar
,而不是更早,但是,目前 Slick 的 Future 完成得太快了。 如果相關:當請求發送到 Akka Http 端點時,將調用doStuff
方法。 應用程序和數據庫在兩個不同的 docker 容器中運行。 我究竟做錯了什么?
此外,我無法忘記我一年半前選擇的用戶名現在有多合適。
用def foo
的flatMap
替換map
。 否則,它將啟動一個Future[Seq[Foo]]
,然后立即返回一個()
,然后被您的doStuff
丟棄。 像這樣的東西:
fooStorage
.truncateFooData()
.flatMap(_ => {
/* stuff... */
fooStorage.saveFooDataBulk(foo.toSeq)
})
.map(_ => ())
我沒有測試它,但無論如何,在另一個Future.map
中間啟動一些Future
,然后立即返回一個()
感覺不太正確。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.