【问题标题】:Embedded H2 database: Multithreaded access嵌入式 H2 数据库:多线程访问
【发布时间】:2020-06-14 06:46:21
【问题描述】:

我有一个程序可以从 HTML 文件中解析出一些数据,然后根据当前日期对这些文件进行一些计算。

由于文件的解析需要很多时间并且它们没有改变,所以我现在将数据存储在嵌入式 H2 数据库中,并且仅当该文件中的数据不在数据库中时才对其进行解析。否则我只是从数据库中查询它。还是初始解析,还有新文件的时候,都需要很多时间。

所以我现在正处于尝试多线程解析的地步。我想使用 ExecutorService 执行此操作并将文件拆分为多个任务(每个文件一个可能不是一个好主意,可能需要 10-20 个任务来使用所有内核)。现在我不知道,我应该如何实现数据库访问。我应该只有一个连接并为每个任务创建所需的 PreparedStatements,还是应该使用连接池(并且还为每个任务创建 PreparedStatements)或其他方式?

【问题讨论】:

  • 一般来说,对于 JDBC,虽然连接应该是线程安全的,但最好不要同时使用来自多个线程的连接,因为它会引入竞争条件(例如,考虑一个线程时会发生什么提交,另一个回滚)。由于连接线程安全,各个操作可能会正常工作,但您预期的工作单元可能(或者更有可能)无法正常工作。

标签: java database multithreading jdbc h2


【解决方案1】:

在 JDBC 中,Connection 对象可能有多个 StatementPreparedStatement 实例,但它们不能同时工作。如果您同时执行一些命令,它们将被一一执行。如果它们不相互依赖并且您不修改它们中的连接设置是安全的,但是您的线程将等待来自其他线程的命令完成。如果您的命令运行速度不够快,这些额外的延迟可能会很明显。在这种情况下,您可以为每个线程创建一个自己的Connection,并从它自己的连接为该线程创建StatementPreparedStatement 实例。不同的连接可以同时执行命令。

在 H2 中,您还需要最新版本的数据库,并且需要使用默认的 MVStore 引擎。旧版 PageStore 引擎 (;MV_STORE=FALSE) 以单线程模式运行。默认情况下,旧版本的 H2 也对两个存储引擎使用单线程模式,并且在它们中显式启用多线程并不完全安全。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-19
    • 2017-03-05
    • 2011-01-27
    • 2012-08-17
    • 2016-01-22
    • 2010-09-14
    • 2014-10-11
    相关资源
    最近更新 更多