如何与外国密钥关系并行插入多个表 我想并行插入多个表,这些表具有外键关系。 我试图做到这一点的方式(以下)不起作用,我会遭受外国密钥违规。 java.lang.exce ...

问题描述 投票:0回答:0
并行(如果可以的话)


能够在任何错误上回滚所有表。

class Scratch (creds: DbCreds, dbType: String, driverClassName: String, initialPoolSize: Int = 4,
               maxPoolSize: Int = 10, queryTimeout: Int = 600000) extends DbConnectionPool with Configs {

  val connectionPool = setConnectionPool(creds, dbType, driverClassName, initialPoolSize, maxPoolSize, queryTimeout)
  implicit val ec = ExecutionContext.global

  def updateTables(): Unit = {

//     these are how the tables are set up: 
//    create table parent (parent_id int primary key);
//    create table child (id int primary key, parent_id int references parent(parent_id));
//    create table child2 (id int primary key, parent_id int references parent(parent_id));

    val parentTableConn: Connection = getNonCommitConnection()
    val childTableConn: Connection  = getNonCommitConnection()
    val childTable2Conn: Connection = getNonCommitConnection()

    try {
      val parentTableFuture = Future {
        updateParent(parentTableConn)
      }
      parentTableFuture.onComplete {
        case Success(x) => println("-parent table updated successfully")
        case Failure(error) => throw new Exception(error)
      }
      Await.result(parentTableFuture, queryTimeout millisecond)
      val childTableFuture = Future {
        updateChild(childTableConn)
      }
      childTableFuture.onComplete {
        case Success(x) => println("-child table updated successfully")
        case Failure(error) => throw new Exception(error)
      }
      val childTable2Future = Future {
        updateChild2(childTable2Conn)
      }
      childTable2Future.onComplete {
        case Success(x) => println("-child2 table updated successfully")
        case Failure(error) => throw new Exception(error)
      }
      parentTableConn.commit()
      childTableConn.commit()
      childTable2Conn.commit()

    } catch {
      case e: Exception => {
        println(s"ERROR: exception thrown rolling back db commits\n${e}")
        parentTableConn.rollback()
        childTableConn.rollback()
        childTable2Conn.rollback()

        throw e
      }
    } finally {
      parentTableConn.close()
      childTableConn.close()
      childTable2Conn.close()
    }
  }

  def updateParent(conn: Connection): Unit = {
    val sql = "insert into parent (parent_id) values (1),(2),(3);"
    val stmt = conn.createStatement()
    stmt.execute(sql)
    stmt.close()
  }

  def updateChild(conn: Connection): Unit = {
    val sql = "insert into child (id, parent_id) values (1,1),(2,2),(3,1);"
    val stmt = conn.createStatement()
    stmt.execute(sql)
    stmt.close()
  }

  def updateChild2(conn: Connection): Unit = {
    val sql = "insert into child2 (id, parent_id) values (1,3),(2,3),(3,1);"
    val stmt = conn.createStatement()
    stmt.execute(sql)
    stmt.close()
  }

}

  1. 这是我对感兴趣的人的解决方案。 同样在我的真实用例中,我还使用了AadrianKlaver
  2. 的建议使用延迟的外键约束。
  3. class Scratch (creds: DbCreds, dbType: String, driverClassName: String, initialPoolSize: Int = 4, maxPoolSize: Int = 10, queryTimeout: Int = 600000) extends DbConnectionPool with Configs { val connectionPool = setConnectionPool(creds, dbType, driverClassName, initialPoolSize, maxPoolSize, queryTimeout) implicit val ec = ExecutionContext.global def updateTables(): Unit = { // create table parent (parent_id int primary key); // create table child (id int primary key, parent_id int references parent(parent_id)); // create table child2 (id int primary key, parent_id int references parent(parent_id)); val tableConn: Connection = getNonCommitConnection() try { updateParent(tableConn) val f = Future { updateChild(tableConn) } f.onComplete({ case Success(_) => println("success1") case Failure(e) => println(s"ERROR: exception thrown rolling back db commits\n${e}") }) val f2 = Future { updateChild2(tableConn) } f2.onComplete({ case Success(_) => println("success2") case Failure(e) => println(s"ERROR: exception thrown rolling back db commits\n${e}") }) tableConn.commit() } catch { case e: Exception => { println(s"ERROR: exception thrown rolling back db commits\n${e}") tableConn.rollback() throw e } } finally { tableConn.close() } } def updateParent(conn: Connection): Unit = { val sql = "insert into parent (parent_id) values (1),(2),(3);" val stmt = conn.createStatement() stmt.execute(sql) stmt.close() } def updateChild(conn: Connection): Unit = { val sql = "insert into child (id, parent_id) values (1,1),(2,2),(3,1);" val stmt = conn.createStatement() stmt.execute(sql) stmt.close() } def updateChild2(conn: Connection): Unit = { val sql = "insert into child2 (id, parent_id) values (1,3),(2,3),(3,1);" val stmt = conn.createStatement() stmt.execute(sql) stmt.close() } }

postgresql scala jdbc
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.