能够在任何错误上回滚所有表。
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()
}
}
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()
}
}