我正在使用带有Scala Play框架2.6的slick 3.2.3。 我正在通过迭代将行插入表中。它有时会成功保存,但有时会在MYSQL中保存几行(缺少某些行)。什么可能是根本原因? MYSQL版本-5.7 这是我的代码
try {
db.run {
documentDetails.map(p => (p.documentDetailsId, p.documentDirectoryId, p.patentId, p.hospitalId, p.clinicId, p.patientType, p.categoryType, p.admissionAppointmentNo, p.documentName, p.status, p.remarks, p.description)) += (docId, documentDirectoryId, patentId, hospitalId, clinicId, patientType, categoryType, admissionAppointmentNo, documentName, true, remarks, description)
}
}
catch {
case e: Exception =>
e.printStackTrace()
logger.error(e.getMessage)
throw e
}
答案 0 :(得分:0)
db.run
返回一个Future
,因此您应该对此Future
进行操作。
顺便说一下,您的try-catch
块不会检查未来是否失败。
尝试
Await.result(db.run(...), Duration.Inf)
如果您认为屏蔽是可以的(取决于此代码的位置)。
答案 1 :(得分:0)
我想最好在DBIO或Future中检查 rowsAffected ...
文档:(受影响的行)
/** Insert multiple rows, skipping AutoInc columns.
* Uses JDBC's batch update feature if supported by the JDBC driver.
* Returns Some(rowsAffected), or None if the database returned no row
* count for some part of the batch. If any part of the batch fails, an
* exception is thrown. */
def ++= (values: Iterable[U]): ProfileAction[MultiInsertResult, NoStream, Effect.Write]
因此在DBIO中:
/**
*
* @param f function throws exception
* @return DBIO.successful --> is good!!!
* DBIO.failed(th) --> is bad :-(
*/
def validate(f: => Unit): DBIOAction[Unit, NoStream, Effect] = try {
DBIO.successful(f)
} catch {
case NonFatal(th) => DBIO.failed(ValidationError(th))
}
def checkRowsAffected(rowsAffect: Int, rowsAffected: Int,
errorMessage: String = "rowAffected not equal rowsAffect"): DBIOAction[Unit, NoStream, Effect] =
validate(require(rowsAffect == rowsAffected, errorMessage))
val BannersInsertQuery = Banners returning Banners.map(_.id)
for {
bannersInserted <- BannersInsertQuery ++= bannersToInsert
_ <- checkRowsAffected(bannersToInsert.length, bannersInserted.length)
} yield bannersInserted
因此将来:(使用db.run)
/**
*
* @param f function throws exception
* @return Future.successful --> is good!!!
* Future.failed(ex) --> is bad :-(
*/
def validate(f: => Unit)(implicit ec: ExecutionContext): Future[Unit] = Future.successful(f).recover {
case ve: ValidationError => Future.failed(ve)
case NonFatal(th) => Future.failed(ValidationError(th))
}
def checkRowsAffected(rowsAffect: Int, rowsAffected: Int,
errorMessage: String = "rowAffected not equal rowsAffect")
(implicit ec: ExecutionContext): Future[Unit] =
validate(require(rowsAffect == rowsAffected, errorMessage))
db.run(BannersInsertQuery ++= bannersToInsert).map( bannersInserted => checkRowsAffected(bannersToInsert.length, bannersInserted.length))