2017-07-12 3 views
0

私はHibernate 4.3.1と一緒にHibernate 1.4.191を使用しています。私のh2接続のURLはdbc:h2:file:./h2/myDBです - MULTI_THREADEDを有効にしない埋め込みDBです。私はMVCCで稼働しています - これは1.4.191のデフォルト設定です。更新HQLのステートメントを実行しようとしているときに自分のアプリケーションにこの設定を使用して組み込みモードでh2の同時更新

は、私は、次のスタックトレースを得た:

2017-07-11 19:38:48 SEVERE Could not set rounding style. org.hibernate.PessimisticLockException: could not execute statement 
    at org.hibernate.dialect.H2Dialect$2.convert(H2Dialect.java:342) 
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49) 
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126) 
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112) 
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190) 
    at org.hibernate.hql.internal.ast.exec.BasicExecutor.doExecute(BasicExecutor.java:109) 
    at org.hibernate.hql.internal.ast.exec.BasicExecutor.execute(BasicExecutor.java:78) 
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:445) 
    at org.hibernate.engine.query.spi.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:347) 
    at org.hibernate.internal.SessionImpl.executeUpdate(SessionImpl.java:1282) 
    at org.hibernate.internal.QueryImpl.executeUpdate(QueryImpl.java:118) 
    at de.oktopos.dataBase.receipts.converter.ReceiptConverter$29.runOperation(ReceiptConverter.java:1214) 
    at de.oktopos.dataBase.receipts.converter.ReceiptConverter$29.runOperation(ReceiptConverter.java:1210) 
    at de.oktopos.dataBase.tools.DatabaseOperationRunner.run(DatabaseOperationRunner.java:71) 
    at de.oktopos.dataBase.receipts.converter.ReceiptConverter.setRoundingStyle(ReceiptConverter.java:1226) 
    at de.oktopos.dataBase.receipts.converter.ReceiptCacheWriter.setRoundingStyle(ReceiptCacheWriter.java:99) 
    at de.oktopos.oktoDeskService.remote.OktoDeskModel.setRoundingStyle(OktoDeskModel.java:841) 
    at net.oktopos.cashdesk.DeskModelProcessor.setRoundingStyle(DeskModelProcessor.java:1648) 
    at sun.reflect.GeneratedMethodAccessor37.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source) 
    at sun.rmi.transport.Transport$1.run(Unknown Source) 
    at sun.rmi.transport.Transport$1.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.transport.Transport.serviceCall(Unknown Source) 
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
    at java.lang.Thread.run(Unknown Source) 
Caused by: org.h2.jdbc.JdbcSQLException: Zeitüberschreitung beim Versuch die Tabelle zu sperren 
Timeout trying to lock table ; SQL statement: 
update Receipt set turnoverType=? [50200-191] 
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:345) 
    at org.h2.message.DbException.get(DbException.java:168) 
    at org.h2.command.Command.filterConcurrentUpdate(Command.java:307) 
    at org.h2.command.Command.executeUpdate(Command.java:260) 
    at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:160) 
    at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:146) 
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:187) 
    ... 29 more 
Caused by: org.h2.jdbc.JdbcSQLException: Gleichzeitige Änderung in Tabelle "RECEIPT": eine andere Transaktion hat den gleichen Datensatz geändert oder gelöscht 
Concurrent update in table "RECEIPT": another transaction has updated or deleted the same row [90131-191] 
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:345) 
    at org.h2.message.DbException.get(DbException.java:168) 
    at org.h2.mvstore.db.MVTable.convertException(MVTable.java:898) 
    at org.h2.mvstore.db.MVSecondaryIndex.remove(MVSecondaryIndex.java:247) 
    at org.h2.mvstore.db.MVTable.removeRow(MVTable.java:677) 
    at org.h2.table.Table.updateRows(Table.java:487) 
    at org.h2.command.dml.Update.update(Update.java:145) 
    at org.h2.command.CommandContainer.update(CommandContainer.java:98) 
    at org.h2.command.Command.executeUpdate(Command.java:258) 
    ... 32 more 
Caused by: java.lang.IllegalStateException: Entry is locked [1.4.191/101] 
    at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:773) 
    at org.h2.mvstore.db.TransactionStore$TransactionMap.set(TransactionStore.java:1031) 
    at org.h2.mvstore.db.TransactionStore$TransactionMap.remove(TransactionStore.java:989) 
    at org.h2.mvstore.db.MVSecondaryIndex.remove(MVSecondaryIndex.java:241) 
    ... 37 more 

イムこれが可能であるかを理解しようとしています。スタックトレースはロックcould not be acquired because of another connection (50200)と言われています。特にそれはanother connection concurrently updated the table (90131)と言います。データベースが埋め込まれているため、1つの接続しかできません。私はここに何かを逃していますか

(マイナスエラー処理の定型は、DBReceiptがレシートにマップ)次のようにHQLクエリは基本的に実行されます。

Session session = sessionFactory.openSession(); 
    Transaction transaction = session.beginTransaction(); 
    session.createQuery("UPDATE DBReceipt SET turnovertype = :turnovertype") 
         .setParameter("turnovertype", turnovertype) 
         .executeUpdate(); 
    transaction.commit(); 
    session.close(); 

はもちろん、他の多くのデータベースが異なるスレッド上でバックグラウンドで読み込み/書き込みがありますが、すべて同じ接続を使用します。

コードの上記の部分が呼び出されたときにエラーが発生し続けました。アプリケーションを再起動しても役立たず、コードの次回の呼び出しで同じ例外が発生します。 DBを削除するだけで助けになりました。

答えて

0

私のコードベースでビットを調べた後に、問題の原因が考えられました。

私は、LockRequestを作成し、領収書テーブルに領収書をロックしていました。このロックが行かない場合(トランザクションが無限ループで終了するため)、後で領収書テーブルを更新すると、上記のスタックトレースが発生します。

LockRequest(無限ループのソースが見つかりませんでした)を削除してこの問題を解決しました。これは、最近アプリケーションレベルで領収書をロックする動きがあり、オプティミスティックロックを使用するアプリケーションに問題がないために可能でした。

この問題を回避するもう1つの方法は、ロック、トランザクション、またはセッションにタイムアウトを追加することです。しかし、私の環境はこれらのどれもサポートしていないようです - 少なくとも私のテストでは働いていませんでした。

関連する問題