【问题标题】:Getting JdbcBatchUpdateException while testing with EmbeddedDatabase H2使用 EmbeddedDatabase H2 进行测试时出现 JdbcBatchUpdateException
【发布时间】:2016-12-24 03:16:03
【问题描述】:

尝试使用 EmbeddedDatabase H2 测试我的代码时遇到奇怪的异常:

java.lang.RuntimeException: 
java.lang.RuntimeException: org.h2.jdbc.JdbcBatchUpdateException: Timeout trying to lock table "CO_SCENARIO_1"; SQL statement:
UPDATE CO_SCENARIO_1 SET VALUE = ? WHERE ATTRIBUTE = ? AND MODIFIER = ? [50200-156]
    at de.telekom.skses.test.dao.DatabaseFileConverterTest.fromFile(DatabaseFileConverterTest.java:99)

这是我要测试的代码的一部分:

case "overriddenVariables.txt": {
                        try (Scanner sc = new Scanner(bOut.toString())) {
                            try (Connection con = dataSource.getConnection()) {
                                String aQuery = "UPDATE $tableName SET VALUE = ? WHERE ATTRIBUTE = ? AND MODIFIER = ?";
                                String line = "";
                                if (sc.hasNext()) {
                                    line = sc.nextLine();
                                }
                                while (sc.hasNext()) {
                                    if (line.startsWith("+")) {
                                        String setting = line.substring(1);
                                        try (PreparedStatement ps = con.prepareStatement(aQuery.replace("$tableName", setting))) {

                                            while (sc.hasNext() && !(line = sc.nextLine()).startsWith("+")) {
                                                int del1 = line.indexOf(":");
                                                int del2 = line.indexOf(':', del1 + 1);
                                                String attr = line.substring(0, del1);
                                                String modifier = line.substring(del1 + 1, del2);
                                                String value = line.substring(del2 + 1, line.length());
                                                Clob myClob = con.createClob();
                                                myClob.setString(1, value);
                                                ps.setClob(1, myClob);
                                                ps.setString(2, attr);
                                                ps.setString(3, modifier);
                                                ps.addBatch();
                                            }
                                            ps.executeBatch();
                                        }

                                    }
                                }

                            } catch (SQLException e) {
                                logger.error("Error", e);
                                throw new RuntimeException(e);
                            }
                        } catch (Exception ex) {
                            logger.error("Error", ex);
                            throw new RuntimeException(ex);
                        }

                        break;
                    }

StackOverflow 说我应该设置锁定超时,但我没有找到如何为 EmbeddedDatabase 设置它。此外,在以前的版本中,我为每个查询打开了新的 PreparedStatement,并为每个 PreparedStatement 打开了新的连接,一切正常,我不明白为什么现在不行。你能解释一下我必须做什么才能让它再次工作吗?

抱歉,如果有什么不正确的地方,我是 Java EE 的新手。

【问题讨论】:

    标签: java sql spring h2


    【解决方案1】:

    我记得在嵌入式模式下使用 H2,它存在并发问题。这可能是您获得表锁定超时的原因,因为当您尝试执行下一个时,该表仍从您的上一批更新。每次关闭连接和preparedStatement时,执行时间会更短,因此您不会超时。

    您是否尝试过按照post 中的说明添加到 DatabaseURL ;MVCC=true?如果这不能解决问题,是否真的需要使用批处理进行更新?

    编辑:我之前链接的帖子链接到h2 website,您可以在其中找到有关如何通过将;LOCK_TIMEOUT=10000 添加到数据库URL 来更改锁定超时的描述。这会将其更改为 10 秒,标准是 1 秒

    【讨论】:

    • 抱歉,如何将此设置添加到 EmbeddedDatabase?我只是像@Bean public EmbeddedDatabase dataSource() { return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2) ... .build() } 那样自动连接数据源
    • 好吧,我只是用谷歌搜索了很多,但如果你没有使用任何 spring.config 文件来指定 URL,我不知道这是否可能。我能想到的唯一方法是使用.setName("testDB;MVCC=true")method 来欺骗它做你想做的事。因为如上所述here spring 使用jdbc:h2:mem:testDb 作为 URL 创建 DB,所以也许通过调用 DB testDB;MVCC=true 它会工作
    • 你可以随意命名它,我只是使用“testDb”;)
    猜你喜欢
    • 2019-04-01
    • 2011-12-31
    • 1970-01-01
    • 2020-07-16
    • 2013-09-14
    • 2019-04-01
    • 2018-09-12
    • 1970-01-01
    • 2023-01-31
    相关资源
    最近更新 更多