H2 数据库恢复到特定状态进行测试

Posted

技术标签:

【中文标题】H2 数据库恢复到特定状态进行测试【英文标题】:H2 database restore to particular state for testing 【发布时间】:2014-09-02 12:34:38 【问题描述】:

我们使用 H2 数据库来执行测试。为了将每个测试与另一个测试隔离开,在每次测试之前删除并重新创建数据库架构和基本数据设置。

是否可以在第一次设置数据库之后创建一个还原点,并在每次测试该点的数据之前还原?

SCRIPT 只是创建一个包含所有表和数据的 sql 文件。与我们自己的初始化没有太大区别。

问题 database restore to particular state for testing 是一样的,只是针对 Oracle 和 Postgres。

【问题讨论】:

怎么样:创建数据库,然后进行备份(文件备份)。在运行每个测试之前,恢复备份?是不是太慢了?将来,对于 H2 版本 1.4.x,可能可以(而不是还原)简单地截断数据库文件。 我认为因为this question,BACKUP 速度较慢,但​​在我重读答案后,我应该测试 BACKUP。 【参考方案1】:

一个老问题,但我发现它仍然相关。 AFAIK 没有还原点支持。

这是一种简单而快速的备份/恢复方法。

在运行第一个测试之前创建备份:

Connection conn = DriverManager.getConnection("jdbc:h2:mem:myDatabase;DB_CLOSE_DELAY=-1;LOG=0");
Statement stat = conn.createStatement();
stat.execute("SCRIPT TO 'memFS:myDatabase.sql'");
stat.close();
conn.close();

每次测试后恢复:

Connection conn = DriverManager.getConnection("jdbc:h2:mem:myDatabase;DB_CLOSE_DELAY=-1;LOG=0");
Statement stat = conn.createStatement();
stat.execute("DROP ALL OBJECTS");
stat.close();
conn.close();

conn = DriverManager.getConnection("jdbc:h2:mem:myDatabase;DB_CLOSE_DELAY=-1;INIT=runscript from 'memFS:myDatabase.sql';LOG=0");
conn.close();

请注意,SHUTDOWN 命令比DROP ALL OBJECTS 更快,但它导致了一些问题(连接池无法重新建立连接)。

我不会说上述方法很慢,远非如此。但是对于大型数据库和数千个测试,仍然有改进的余地,因为上述方法需要一些时间。我设法使备份/恢复速度提高了几倍(对于具有约 350 个表的数据库,约 15 毫秒)手动编写执行TRUNCATE TABLEALTER SEQUENCE 的脚本并执行所有初始数据的INSERT(需要SET REFERENTIAL_INTEGRITY FALSE清理/恢复过程非常快)。代码很麻烦,但值得付出努力。

【讨论】:

对我来说效果很好!虽然我使用 connection.createStatement().execute("RUNSCRIPT FROM 'memFS:myDatabase.sql'") 而不是 INIT

以上是关于H2 数据库恢复到特定状态进行测试的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot DataJpaTest 单元测试恢复到 H2 而不是 mySql

恢复 h2 数据库

根据备份文件和 oplog恢复数据到某个时间点,为啥报不能恢复

在分支合并之前恢复到特定状态

如何将文件重置或恢复到特定版本?

H2 数据库 - 在控制台中恢复配置