48

特定のシナリオで次のエラーが発生します

別のスレッドが一括アップロード操作を介して多数のユーザーを取り込み、別の Web ページですべてのユーザーのリストを表示しようとしたとき。リスト クエリは、次のタイムアウト エラーをスローします。このタイムアウト エラーを回避できるように、このタイムアウトを設定する方法はありますか。

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
4

8 に答える 8

50

はい、ロック タイムアウトを変更できます。デフォルトは比較的低く、1 秒 (1000 ミリ秒) です。

多くの場合、問題は別の接続がテーブルをロックしていることであり、複数バージョンの同時実行を使用すると問題も解決します (;MVCC=trueデータベース URL に追加します)。

編集: MVCC=trueparam はサポートされなくなりました。これは、 h2 1.4.200以降、デフォルト エンジンである MVStore エンジンに対して常に true であるためです。

于 2010-11-12T08:09:10.470 に答える
39

私はまったく同じ問題に直面し、パラメータ「MVCC = true」を使用して解決しました。このパラメーターの詳細については、H2 ドキュメント ( http://www.h2database.com/html/advanced.html#mvcc ) を参照してください。

于 2011-06-15T11:44:42.287 に答える
6

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.

于 2012-10-28T17:09:17.640 に答える
6

統合テストでこの問題が発生している場合 (つまり、サーバーが h2 db にアクセスしており、統合テストがテストを準備するためにサーバーを呼び出す前に db にアクセスしている場合)、テストの前に実行されるスクリプトに「commit」を追加すると、データはサーバーを呼び出す前にデータベースにあります(MVCC = trueなし-デフォルトで有効になっていない場合、これは少し「奇妙」です)。

于 2011-11-07T14:25:39.283 に答える
1

PlayFramework でこの問題が発生しました

JPAQueryException が発生しました: models.Page からクエリを実行中にエラーが発生しました。名前 = ?: テーブル "PAGE" をロックしようとしてタイムアウトしました

私が持っていたので、それはある種の無限ループで終わった

@前

関数が繰り返し自分自身を呼び出す原因となった、unless なし

@Before(unless="getUser")

于 2011-09-18T22:30:22.957 に答える