尝试锁定 h2 中的表时出现超时错误

发布于 2024-10-02 05:59:20 字数 1860 浏览 8 评论 0原文

我收到以下错误

在特定情况下,当不同的线程通过批量上传操作填充大量用户并且我试图查看不同网页上的所有用户的列表时, 。列表查询抛出以下超时错误。有没有办法设置这个超时,这样我就可以避免这个超时错误。

环境:h2(最新),Hibernate 3.3.x

Caused by: org.h2.jdbc.JdbcSQLException: Timeout trying to lock table "USER"; SQL statement:

[50200-144]

    at org.h2.message.DbException.getJdbcSQLException(DbException.java:327)
    at org.h2.message.DbException.get(DbException.java:167)
    at org.h2.message.DbException.get(DbException.java:144)
    at org.h2.table.RegularTable.doLock(RegularTable.java:482)
    at org.h2.table.RegularTable.lock(RegularTable.java:416)
    at org.h2.table.TableFilter.lock(TableFilter.java:139)
    at org.h2.command.dml.Select.queryWithoutCache(Select.java:571)
    at org.h2.command.dml.Query.query(Query.java:257)
    at org.h2.command.dml.Query.query(Query.java:227)
    at org.h2.command.CommandContainer.query(CommandContainer.java:78)
    at org.h2.command.Command.executeQuery(Command.java:132)
    at org.h2.server.TcpServerThread.process(TcpServerThread.java:278)
    at org.h2.server.TcpServerThread.run(TcpServerThread.java:137)
    at java.lang.Thread.run(Thread.java:619)
    at org.h2.engine.SessionRemote.done(SessionRemote.java:543)
    at org.h2.command.CommandRemote.executeQuery(CommandRemote.java:152)
    at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:96)
    at org.jboss.resource.adapter.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:342)
    at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:1808)
    at org.hibernate.loader.Loader.doQuery(Loader.java:697)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
    at org.hibernate.loader.Loader.doList(Loader.java:2228)
    ... 125 more

I get the following error under a certain scenario

When a different thread is populating a lot of users via the bulk upload operation and I was trying to view the list of all users on a different web page. The list query, throws the following timeout error. Is there a way to set this timeout so that I can avoid this timeout error.

Env: h2 (latest), Hibernate 3.3.x

Caused by: org.h2.jdbc.JdbcSQLException: Timeout trying to lock table "USER"; SQL statement:

[50200-144]

    at org.h2.message.DbException.getJdbcSQLException(DbException.java:327)
    at org.h2.message.DbException.get(DbException.java:167)
    at org.h2.message.DbException.get(DbException.java:144)
    at org.h2.table.RegularTable.doLock(RegularTable.java:482)
    at org.h2.table.RegularTable.lock(RegularTable.java:416)
    at org.h2.table.TableFilter.lock(TableFilter.java:139)
    at org.h2.command.dml.Select.queryWithoutCache(Select.java:571)
    at org.h2.command.dml.Query.query(Query.java:257)
    at org.h2.command.dml.Query.query(Query.java:227)
    at org.h2.command.CommandContainer.query(CommandContainer.java:78)
    at org.h2.command.Command.executeQuery(Command.java:132)
    at org.h2.server.TcpServerThread.process(TcpServerThread.java:278)
    at org.h2.server.TcpServerThread.run(TcpServerThread.java:137)
    at java.lang.Thread.run(Thread.java:619)
    at org.h2.engine.SessionRemote.done(SessionRemote.java:543)
    at org.h2.command.CommandRemote.executeQuery(CommandRemote.java:152)
    at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:96)
    at org.jboss.resource.adapter.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:342)
    at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:1808)
    at org.hibernate.loader.Loader.doQuery(Loader.java:697)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
    at org.hibernate.loader.Loader.doList(Loader.java:2228)
    ... 125 more

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

舞袖。长 2024-10-09 05:59:20

是的,您可以更改锁定超时。默认值相对较低:1 秒(1000 毫秒)。

在许多情况下,问题是另一个连接锁定了表,使用多版本并发也可以解决问题(将 ;MVCC=true 附加到数据库 URL)。

编辑:不再支持 MVCC=true 参数,因为自 h2 1.4 .200 对于 MVStore 引擎来说始终如此,它是默认引擎。

Yes, you can change the lock timeout. The default is relatively low: 1 second (1000 ms).

In many cases the problem is that another connection has locked the table, and using multi-version concurrency also solves the problem (append ;MVCC=true to the database URL).

EDIT: MVCC=true param is no longer supported, because since h2 1.4.200 it's always true for a MVStore engine, which is a default engine.

遗心遗梦遗幸福 2024-10-09 05:59:20

我遇到了完全相同的问题并使用参数“MVCC=true”,它解决了它。您可以在 H2 文档中找到有关此参数的更多说明:http://www.h2database.com/html/高级.html#mvcc

I faced quite the same problem and using the parameter "MVCC=true", it solved it. You can find more explanations about this parameter in the H2 documentation here : http://www.h2database.com/html/advanced.html#mvcc

四叶草在未来唯美盛开 2024-10-09 05:59:20

我想建议,如果您收到此错误,那么也许您不应该在批量数据库操作中使用事务。考虑对每个单独的更新执行事务:将整个批量导入视为事务是否有意义?可能不会。如果确实如此,那么 MVCC=true 或更大的锁定超时是一个合理的解决方案。

但是,我认为在大多数情况下,您看到此错误是因为您正在尝试执行非常长的事务 - 换句话说,您不知道自己正在执行非常长的事务。我自己就是这种情况,我只是更加注意如何写入记录(不使用事务或使用较小的事务),并且锁定超时问题得到了解决。

I'd like to suggest that if you are getting this error, then perhaps you should not be using a transaction on your bulk database operation. Consider instead doing a transaction on each individual update: does it make sense to think of an entire bulk import as a transaction? Probably not. If it does, then yes, MVCC=true or a bigger lock timeout is a reasonable solution.

However, I think for most cases, you are seeing this error because you are trying to perform a very long transaction - in other words you are not aware that you are performing a really long transaction. This was certainly the case for myself and I simply took more care on how I was writing records (either using no transactions or using smaller transactions) and the lock timeout issue was resolved.

倦话 2024-10-09 05:59:20

对于那些在集成测试中遇到此问题的人(即服务器正在访问 h2 数据库,并且集成测试在调用服务器之前访问数据库以准备测试),请在测试之前向执行的脚本添加“提交”以确保在调用服务器之前,数据位于数据库中(没有 MVCC=true - 我发现如果默认情况下未启用它有点“奇怪”)。

For those having this issue with integration tests (i.e. server is accessing the h2 db and an integration test is accessing the db before calling the server, to prepare the test), adding a 'commit' to the script executed before the test makes sure that the data are in the database before calling the server (without MVCC=true - which I find is a bit 'weird' if it is not enabled by default).

终止放荡 2024-10-09 05:59:20

我的连接字符串中有 MVCC=true 但仍然出现上面的错误。我添加了 ;DEFAULT_LOCK_TIMEOUT=10000;LOCK_MODE=0 并解决了问题

I had MVCC=true in my connection string but still was getting error above. I had added ;DEFAULT_LOCK_TIMEOUT=10000;LOCK_MODE=0 and problem was solved

姐不稀罕 2024-10-09 05:59:20

对于 2020 年的用户,请参阅 参考

基本上,该参考说:

设置当前会话的锁定超时(以毫秒为单位)。此设置的默认值为 1000(一秒)。

该命令不会提交事务,回滚不会影响它。可以将此设置附加到数据库 URL:jdbc:h2:./test;LOCK_TIMEOUT=10000

From a 2020 user, see reference

Basically, the reference says:

Sets the lock timeout (in milliseconds) for the current session. The default value for this setting is 1000 (one second).

This command does not commit a transaction, and rollback does not affect it. This setting can be appended to the database URL: jdbc:h2:./test;LOCK_TIMEOUT=10000

绅士风度i 2024-10-09 05:59:20

我在 PlayFramework 中遇到了这个问题

发生 JPAQueryException:执行查询时出错
models.Page where name = ?: 尝试锁定表“PAGE”超时

它最终成为一种无限循环,因为我有一个

@之前

没有 except 会导致函数重复调用自身

@之前(除非=“getUser”)

I got this issue with the PlayFramework

JPAQueryException occured : Error while executing query from
models.Page where name = ?: Timeout trying to lock table "PAGE"

It ended being an infinite loop of sorts because I had a

@Before

without an unless which caused the function to repeatedly call itself

@Before(unless="getUser")

等待我真够勒 2024-10-09 05:59:20

使用 DBUnit、H2 和 Hibernate - 同样的错误,MVCC=true 有所帮助,但在删除数据后的任何测试中我仍然会收到错误。解决这些情况的方法是将实际的删除代码包装在事务中:

Transaction tx = session.beginTransaction();
...delete stuff
tx.commit(); 

Working with DBUnit, H2 and Hibernate - same error, MVCC=true helped, but I would still get the error for any tests following deletion of data. What fixed these cases was wrapping the actual deletion code inside a transaction:

Transaction tx = session.beginTransaction();
...delete stuff
tx.commit(); 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文