【问题标题】:H2 server suspends while debuggingH2 服务器在调试时挂起
【发布时间】:2015-11-12 22:23:58
【问题描述】:

我有一个 Spring 应用程序,它在内存 H2 数据库中启动以下 JUnit 测试:

db.jdbc.driver=org.h2.Driver
db.jdbc.url=jdbc:h2:mem:sampledb
db.jdbc.username=
db.jdbc.password=
hibernate.dialect=org.hibernate.dialect.H2Dialect

我想在我的 JUnit 测试运行时轻松调试,同时浏览数据库状态,所以在测试套件之前我启动 H2 Server:

org.h2.tools.Server.createTcpServer("-tcpPort", "9092", "-tcpAllowOthers").start();

不幸的是,当我放置任何暂停所有线程的断点时,它也会暂停 H2 服务器线程,所以我无法连接。我无法在不同的进程中启动 H2 服务器,因为无法从外部 VM 访问内存数据库。

我知道我可以使用其他类型的断点(仅暂停当前线程),但这是一种限制。对于此类问题,您是否找到了其他解决方案?

【问题讨论】:

    标签: java multithreading spring junit h2


    【解决方案1】:

    在这里启动 tcp 服务器无济于事,因为您正在创建内存数据库。

    我建议改为在线程中启动控制台,并在同一段代码中(例如使用 jdbc)打开与该数据库的连接,但不要关闭/释放它。 p>

    使用这个 sn-p 执行此操作:请根据 H2 文档添加诸如允许其他人之类的选项(我建议暂时保留它)

    org.h2.tools.Server.createWebServer().start();
    

    使用 jdbc/jooq 在第二个线程中打开数据库将如下所示(这是在 Nashorn javascript 中,但可以很容易地适应 java):

    var conn = (new org.h2.Driver()).connect('jdbc:h2:mem:sampledb',new java.util.Properties());
    var DB = org.jooq.impl.DSL.using(conn, org.jooq.SQLDialect.H2);
    

    这样,基于内存的数据库不会被意外关闭,您将能够远程访问它。希望把它放在一个线程中可以保护你免受断点的影响。

    更新:根据与此问题原作者的讨论,最好的解决方案是在单独的进程中打开基于内存的 H2 并在其上提供 tcp 服务器。这解决了问题,但在一个单独的过程中。

    以下是如何启动单独的进程:

    java -jar h2-1.4.188.jar -tcp -tcpPort 9092 -baseDir mem:mydb
    

    这是要使用的 JDBC 网址:jdbc:h2:tcp://localhost:9092/mem:mydb

    重要提示:如果此基于内存的数据库上的所有连接都已关闭,则内容将消失。所以这个方法要慎用。如果您需要通过测试保持持久性,请使用标准的基于文件的 H2 DB。

    【讨论】:

    • 感谢您的回答,但 Web 服务器的工作方式与 tcp 服务器相同。我可以使用两种方法连接到服务器:启动 tcp 服务器时的 tcp 协议和启动 Web 服务器时的 Web 浏览器。问题是当调试器挂起所有线程时,到数据库的远程连接连接被冻结。我想我将在单独的进程中启动一个数据库和一个 tcp 服务器,并从 Junit 测试远程连接到它。
    • 如果这样做,您将无法从另一个进程访问内存数据库。我建议你转移到基于文件的数据库。
    • 我将能够 - 通过 tcp 协议使用远程连接。使用基于文件的 h2 数据库,由于文件被锁定,我无法同时连接到同一个数据库。
    • jdbc:h2:mem:sampledb 表示它是一个内存数据库。您无法使用 tcp 协议访问它,但您可以使用 H2 控制台访问它,前提是它是由同一个 JVM 启动的。这是我回答的重点。
    • @Konrad 我已经更新了答案。我建议谨慎使用基于内存的数据库。祝你考试顺利!
    【解决方案2】:

    有点老问题,但是对于那些碰巧偶然发现这个线程并正在寻找简单答案的人:

    基本上,您可以将调试器断点设置为暂停所有线程(在这种情况下,H2 服务器也将暂停)或仅暂停当前线程 - 这是您正在寻找的设置,H2 服务器将继续运行。

    例如如果您使用 IntelliJ,则右键单击断点(或 Ctrl + Shift + F8 打开“断点”对话框窗口)并设置“暂停线程”

    【讨论】:

      【解决方案3】:

      作为帕维尔奥斯。提到暂停一个线程并结合使用 AUTO_SERVER 选项工作正常!我的 Spring 引导配置如下所示:

      spring.datasource.url=jdbc:h2:~/test:testdb;AUTO_SERVER=TRUE
      spring.datasource.driverClassName=org.h2.Driver
      spring.datasource.username=sa
      spring.datasource.password=password
      

      IntelliJ db 配置如下:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-25
        • 2023-04-02
        • 2017-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-04
        • 1970-01-01
        相关资源
        最近更新 更多