我试图将一系列记录插入两个表中,其中第二个表'主键也是第一个表的外键。 ID。第二个表对另一列也有唯一约束。我需要插入第一个,获取其id(AutoInc),然后插入第二个。插入新记录工作正常,但如果我尝试插入现有记录,整个系统似乎停止工作。我正在使用akka流从(相当大的)文件中流式传输记录,并按记录调用insert方法记录。失败后,我不明白为什么整个流停止。它就像未来永远不会完成,即使打印错误。
代码:
def actorSystem: ActorSystem = ActorSystem("loader")
def materializer: ActorMaterializer = ActorMaterializer()(actorSystem)
def ex: ExecutionContext = actorSystem.dispatcher
import com.mchange.v2.c3p0.ComboPooledDataSource
val database = {
val ds = new ComboPooledDataSource
ds.setDriverClass("org.postgresql.Driver")
ds.setJdbcUrl("...")
ds.setUser("...")
ds.setPassword("...")
Database.forDataSource(ds)
}
val db = database
val reader = CSVReader.open(args(0))
val kind = "postcode"
Source.fromIterator(() => reader.iteratorWithHeaders)
.map(l =>
((l.get("pcd").get, l.get("pcd").get, kind),(l.get("pcd").get.toLowerCase.replaceAll("\\s",""), l.get("osward").get.toLowerCase.replaceAll("\\s","")))
)
.map({i => println(i); i})
.runWith(Sink.foreach({i => insert(i._1, i._2)}))(materializer)
def insert(location: (String, String, String), pc: (String, String)): Unit = {
println("begin")
val locationInsert = LocationTable.rows.map(l => (l.name, l.description, l.kind)) returning LocationTable.rows.map(_.id)
val pcInsert = PostcodeLocationTable.rows.map(r => (r.id, r.postcode, r.osward))
import scala.concurrent.ExecutionContext.Implicits.global
val fullInsert = for {
l <- locationInsert += location
_ <- pcInsert += (l, pc._1, pc._2)
} yield ()
val f = db.run(fullInsert.transactionally)
f.onComplete{
case Success(i) => println(s"inserted $i rows")
case Failure(ex) => println(s"errorrrr ${ex.getMessage}")
}
Await.result(f, Duration(1, SECONDS))
println("end")
}
输出:
((AB1 0AA,AB1 0AA,postcode),(ab10aa,s13002484))
begin
errorrrr ERROR: duplicate key value violates unique constraint "PostcodeLocation_postcode_79955aee_uniq"
Detail: Key (postcode)=(ab10aa) already exists.
即使持续时间设置为1秒,Await呼叫也不会进行。它就像错误导致一切都陷入僵局。如果我以交易方式删除,结果相同。