与内存数据库中的同一个 H2 建立多个连接[重复]

Posted

技术标签:

【中文标题】与内存数据库中的同一个 H2 建立多个连接[重复]【英文标题】:Make multiple connections to same H2 In memory Database [duplicate] 【发布时间】:2018-09-29 23:55:43 【问题描述】:

我经常遇到同样的问题:我想使用内存数据库对我的 DAO 执行单元测试。我正在使用 H2,但我相信问题与 HSQLDB 几乎相同。我的单元测试涉及三个步骤:

创建数据库并设置数据库架构(例如使用 SQL 脚本) 在数据库中插入测试所需的数据(例如:使用 DbUnit) 进行实际测试

在非常简单的情况下,可以在所有三个步骤中使用相同的连接,但是一旦事情变得有点复杂(例如,使用框架查询数据库而不是直接使用 PreparedStatements 时),每个步骤需要一个连接。

问题:数据库似乎在连接关闭后立即被删除。如何解决?

【问题讨论】:

请注意,默认情况下,当连接关闭时,内存数据库将被丢弃。您可以覆盖此行为。请参阅:Keep H2 in-memory database between connectionsH2 in-memory database. Table not found 【参考方案1】:

关于这个话题,H2 documentation 给出了两个提示:

有时到同一个内存数据库的多个连接是 必需的。在这种情况下,数据库 URL 必须包含名称。例子: jdbc:h2:mem:db1。仅使用此 URL 访问同一数据库有效 在同一个虚拟机和类加载器环境中。

默认情况下,关闭与数据库的最后一个连接会关闭 数据库。对于内存数据库,这意味着内容丢失。 要保持数据库打开,请将;DB_CLOSE_DELAY=-1 添加到数据库 网址。保持内存数据库的内容只要 虚拟机还活着,使用jdbc:h2:mem:test;DB_CLOSE_DELAY=-1

所以第一个解决方案是将;DB_CLOSE_DELAY=-1 添加到h2 url。但我对它有点不满意,因为它说数据库将永远留在内存中,而我希望它只在我的测试运行时才存在。

关于DB_CLOSE_DELAY 的文档提供了更多信息:

如果所有连接都关闭,则设置关闭数据库的延迟。值 -1 表示数据库永远不会关闭,直到关闭延迟设置为其他值或调用 SHUTDOWN。值 0 表示无延迟(默认值;如果与数据库的最后一个连接已关闭,则数据库将关闭)。值 1 和更大的值表示关闭最后一个连接后数据库保持打开状态的秒数。

它提示其他解决方案,例如在关机前稍微延迟或手动调用SHUTDOWN(我还没有找到如何在内存数据库上使用它)。

最后是我的整理方法:由于数据库在 last 连接关闭时关闭,我将只保持打开一个 blank 连接 从我创建的那一刻起数据库,直到我不再需要它为止。这种解决方法有点老套(让备用连接打开只是为了让数据库保持活动状态基本上是一种浪费),但它是迄今为止我找到的最优雅的解决方案。这是一个非常简化的抽象单元测试类的 sn-p 来说明这个解决方案:

import org.h2.jdbcx.JdbcDataSource;
public abstract class AbstractTestDao 

private Connection blankConnection;

private DataSource dataSource;

protected DataSource getDataSource() 
    return dataSource;


@Before
public void setup() throws SQLException 
    JdbcDataSource jdbcDataSource = new JdbcDataSource();
    jdbcDataSource.setUrl("jdbc:h2:mem:test");
    this.dataSource = jdbcDataSource;

    this.blankConnection = dataSource.getConnection();


@After
public void tearDown() throws SQLException 
    this.blankConnection.close();


儿童单元测试类将继承这一类并使用提供的 DataSource 对象来初始化用于查询数据库的库,以及执行问题中列出的其他两个步骤。测试完成后,空白连接关闭,内存数据库也关闭。

【讨论】:

以上是关于与内存数据库中的同一个 H2 建立多个连接[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何跨多个 Spring Boot 应用程序共享 H2 内存数据库?

提供多个表时,简单连接在 H2 数据库中不起作用

如何关闭 h2 内存数据库?

连接表时H2数据库重复行

[h2两个数据库同步更新]h2数据库配置多个连接

多个H2数据库连接,不同的访问方式