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

1yjd4xko  于 2021-06-30  发布在  Java
关注(0)|答案(8)|浏览(541)

在某种情况下,我得到以下错误
当一个不同的线程通过批量上传操作填充大量用户时,我试图查看不同网页上所有用户的列表。列表查询抛出以下超时错误。有没有办法设置这个超时,这样我就可以避免这个超时错误。
env: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
iq3niunx

iq3niunx1#

是的,您可以更改锁定超时。默认值相对较低:1秒(1000毫秒)。
在许多情况下,问题是另一个连接锁定了表,使用多版本并发也解决了这个问题(append) ;MVCC=true 到数据库url)。
编辑: MVCC=true param不再受支持,因为自从h2 1.4.200以来,mvstore引擎总是这样,这是一个默认引擎。

qnyhuwrf

qnyhuwrf2#

我的连接字符串中有mvcc=true,但上面仍然有错误。我补充道 ;DEFAULT_LOCK_TIMEOUT=10000;LOCK_MODE=0 问题解决了

kt06eoxx

kt06eoxx3#

对于集成测试有此问题的用户(即服务器正在访问h2 db,集成测试正在调用服务器之前访问db,以准备测试),向测试前执行的脚本添加一个“commit”可以确保在调用服务器之前数据在数据库中(没有mvcc=true-如果默认情况下没有启用它,我发现这有点“奇怪”)。

mxg2im7a

mxg2im7a4#

对于2020用户,请参阅参考资料
基本上,参考文献说:
设置当前会话的锁定超时(毫秒)。此设置的默认值为1000(1秒)。
此命令不提交事务,回滚也不影响事务。此设置可以附加到数据库url: jdbc:h2:./test;LOCK_TIMEOUT=10000

nbnkbykc

nbnkbykc5#

我也遇到了同样的问题,使用参数“mvcc=true”就解决了这个问题。您可以在h2文档中找到有关此参数的更多说明:http://www.h2database.com/html/advanced.html#mvcc

o2g1uqev

o2g1uqev6#

使用dbunit、h2和hibernate-同样的错误,mvcc=true有帮助,但是删除数据之后,我仍然会得到任何测试的错误。解决这些问题的方法是在事务中 Package 实际的删除代码:

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

06odsfpq7#

我的游戏框架有问题
jpaqueryexception发生:从models.page执行查询时出错,其中name=?:尝试锁定表“page”超时
因为我有一个
@之前
除非导致函数重复调用自身
@之前(除非=“getuser”)

a6b3iqyw

a6b3iqyw8#

我想建议,如果您遇到这个错误,那么您不应该在批量数据库操作中使用事务。考虑在每个单独的更新上执行一个事务:将整个批量导入视为一个事务有意义吗?可能不会。如果是这样,那么mvcc=true或更大的锁超时是一个合理的解决方案。
但是,我认为在大多数情况下,您看到这个错误是因为您试图执行一个非常长的事务—换句话说,您没有意识到您正在执行一个非常长的事务。对于我自己来说,情况确实如此,我只是更加注意如何编写记录(要么不使用事务,要么使用较小的事务),锁定超时问题得到了解决。

相关问题