【问题标题】:How can I get H2 to work with Spring?如何让 H2 与 Spring 一起使用?
【发布时间】:2011-03-25 05:26:40
【问题描述】:

我正在编写一个扩展 Spring 的 AbstractTransactionalJUnit4SpringContextTests 的测试。

在我的应用程序代码中,我有一个在测试中调用的方法,并带有以下注释:

@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)

问题

我在使用H2 作为底层数据源内存模式时遇到了问题。它给了我错误:

Caused by:org.h2.jdbc.JdbcSQLException: Timeout trying to lock tableMY_TABLE[50200-131]

当我删除传播时,它可以工作,而当我将 Oracle 或 MySQL 等替代数据库与 Propagation.REQUIRES_NEW 一起使用时,一切正常。

我正在使用 Spring 3.0.2-RELEASEH2 1.2.131

如何让H2 使用 Spring?

【问题讨论】:

  • 使用 Propagation.REQUIRES_NEW 可能会打开一个新连接并因此创建一个新事务。这会导致并发问题,因为 junit spring 测试中当前正在运行事务,该事务已将数据插入表中,从而导致表锁定。我不明白使用 H2 的其他人是如何避免这个问题的!
  • 我切换到 HSQLDB 1.8.0.10 并在我的测试方法上使用了 Propagation.REQUIRES_NEW,一切正常。这告诉我 H2 必须需要配置。
  • 您的交易需要多长时间? H2 的默认事务超时相对较短(1 秒),因此除非您可以缩短事务,否则您可能需要增加 LOCK_TIMEOUT 设置(请参阅文档)。

标签: java spring testing h2


【解决方案1】:

我不知道问题出在哪里,但请尝试将 ;MVCC=TRUE 附加到数据库 URL。

【讨论】:

【解决方案2】:

在使用 play-framework Jobs(运行到单独的线程)和 Thomas 提供的技巧进行 JUnit 测试时遇到了同样的问题! (将 ;MVCC=TRUE 附加到数据库 URL。)

我猜这个 MVCC 选项启用了“行级别锁定”而不是锁定整个 TABLE,因此 LOCK 问题消失了,请参阅“行级别锁定”功能: http://www.h2database.com/html/features.html#in_memory_databases

H2 支持“行级锁定”:

【讨论】:

    猜你喜欢
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多