我正在尝试使用DB actor将记录插入数据库。我有数百万的记录。但是在操作之后,数据库只有十条记录。我知道数据库连接是一个状态,我认为这种情况有问题。这是我的代码代表。
class DBActor extends Actor with DBConfig {
override def receive: Receive = {
case Message(id, title) =>
db.run(products += Product(id, title))
}
}
数据库是关系数据库,'products'是TableQuery,DBConfig有数据库连接和会话。在保证下插入记录的最佳方法是什么。
答案 0 :(得分:3)
使用批次而不是逐个来保留记录。 db.run()方法是异步的,所以它返回将来的立即执行,稍后在不同的线程上执行,因此除了方法调用(db.run)之外,Actor没有做任何事情。你应该使用resister回调(onFailure)关于db.run()方法的结果,以便您可以查看是否发生任何故障。参见示例(它不是编译代码):
case object Insert
case object Flush
class DBActor extends Actor with DBConfig {
implicit val dispatcher = context.dispatcher
val bulkLimit:Int = 1000
val flushTime:Int = 10
var documents = List.empty[Product]
/***
* Start automatic flushing when actor start
*/
context.system.scheduler.scheduleOnce(flushTime second, self, Flush)
def receive:Receive={
case document: Document =>
documents =documents :+ document
log.info(s"DBActor received document [total count ${documents.length}]")
if (documents.length >= bulkLimit) self ! Insert
case Insert =>
if (documents.length > 0) {
val batch = documents.take(bulkLimit)
db.run(products ++= batch).onFailure { case ex: Exception => log.error("Getting error on persisting data", ex) }
documents = documents.drop(bulkLimit)
}
case Flush =>
if (documents.length > 0) self ! Insert
context.system.scheduler.scheduleOnce(flushTime second, self, Flush)
}
}