当外部事件发生时(传入的测量数据),我的Java代码中的事件处理程序正在被调用。应将数据写入MySQL数据库。由于这些呼叫的频率很高(每秒大于1000),我想有效地处理插入。不幸的是,我不是一个专业的开发人员和数据库的白痴。
忽略效率方面我的代码看起来大致如下:
public class X {
public void eventHandler(data) {
connection = DriverManager.getConnection()
statement = connection.prepareStatement("insert …")
statement.setString(1, data)
statement.executeUpdate()
statement.close()
connection.close()
}
}
我的理解是通过在语句上调用 addBatch()和 executeBatch(),我可以限制物理磁盘访问权限让我们说每个第1000次插入。但是,正如您在上面的代码草图中所看到的,语句对象是每次调用 eventHandler()时新实例化的。因此,我的印象是批处理机制在这种情况下没有帮助。同样关闭自动提交,然后在连接对象上调用 commit(),因为每次插入后都会关闭它。
我可以将连接和语句从局部变量转换为类成员,并在程序的整个运行时重用它们。但是,始终保持数据库连接打开不是不好的风格吗?
解决方案是手动缓冲数据,然后在收集适当的批次后才写入数据库。但到目前为止,我仍然希望你聪明的人会告诉我如何让数据库为我做缓冲。
答案 0 :(得分:1)
我可以将连接和语句从局部变量转换为类 成员并在程序的整个运行时期间重用它们。但 保持数据库连接打开根本不是坏风格 时间?
考虑到大多数(数据库)连接池通常配置为始终保持至少一个或多个连接打开,我不会称之为“坏样式”。这是为了避免在每个数据库操作上启动新连接的开销(除非必要,如果所有已打开的连接都在使用且池允许更多)。
在这种情况下,我可能会采用某种形式的批处理(但当然我不知道您的所有要求/环境等)。如果数据不需要立即在其他地方可用,您可以构建某种形式的作业队列来写入数据,将传入的数据推送到那里并让其他线程处理以N大小批次将其写入数据库。看一下java.util.concurrent - 包中可用的课程。
答案 1 :(得分:0)
我建议您使用LinkedList<>
来缓冲数据(如队列),然后在需要时在单独的线程中将数据存储到dbms中,定期执行(可能每2秒一次? )