Slick 3多个依赖插入导致死锁

时间:2016-07-08 16:55:31

标签: scala slick akka-stream

我试图将一系列记录插入两个表中,其中第二个表'主键也是第一个表的外键。 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呼叫也不会进行。它就像错误导致一切都陷入僵局。如果我以交易方式删除,结果相同。

0 个答案:

没有答案