如果一个线程写入和一个读取,H2 数据库开始抛出异常

Posted

技术标签:

【中文标题】如果一个线程写入和一个读取,H2 数据库开始抛出异常【英文标题】:H2 database starts throwing exceptions if one thread writes and one reads 【发布时间】:2014-05-11 15:46:22 【问题描述】:

我使用H2 database 作为对应用程序进行单元测试的持久层。我使用 H2 作为内存数据库。

单元测试将大量数据加载到单个transactions 表中(创建数据库时仅包含此表)。有一个线程根据一些定义的处理规则创建、更新和删除行。这些操作是连续的,并且运行良好,以全速执行。

然后我添加了另一个线程,该线程从表中读取插入的记录数(它只是一个select count(*) from transactions),以查看我在数据加载时所处的位置,H2 开始吐出TABLE_OR_VIEW_NOT_FOUND_1 的异常(42102 错误代码)。它找不到的表是transactions 表。我正在使用JdbcConnectionPool 来获得到数据库的两个连接。

我知道 H2 数据库引擎是单线程的,但我的理解是它会锁定整个表以进行并发操作,这意味着读取将被写入阻塞,反之亦然,但不会出现这样的愚蠢错误。

有人遇到过吗?可能是什么原因?

【问题讨论】:

在某些配置中,H2 会为每个连接创建一个新数据库,因此它们不会同时拥有该表...您的配置未共享,但这可能是罪魁祸首吗? @tariksbl:我没有意识到这一点。这些是什么配置? 实际上这仅适用于 in-mem 模式,但如果是这种情况,请参阅h2database.com/html/cheatSheet.html,两个 mem url 选项。 @tariksbl:我确实在内存中使用 H2。我将其添加到我的问题中,并将尝试看看这是否是问题所在。您介意将您的评论扩展到答案吗? 【参考方案1】:

根据 jdbc url,in-memory mode 中的 H2 可以为每个新连接创建一个新的私有数据库(例如 jdbc:h2:mem:),或者由同一 VM 中使用相同 URL 的多个连接共享的数据库(例如 @987654323 @)。

如果您使用的是私有数据库(以前的)URL,可能是第二个连接正在创建一个没有第一个连接创建的表定义的新数据库?

【讨论】:

以上是关于如果一个线程写入和一个读取,H2 数据库开始抛出异常的主要内容,如果未能解决你的问题,请参考以下文章

在锁 c#2 中抛出异常

H2 不保存价值,不抛出任何异常

Java中的命名管道和多线程

Hibernate/H2 外键抛出 org.h2.jdbc.JdbcSQLException

C ++如果一个线程写入一旦完成就会切换一个布尔值,那么在另一个线程的循环中读取该布尔值是不是安全?

多个 OpenMP 线程读取(不写入)共享变量的性能成本?