web-dev-qa-db-ja.com

Hibernateは悲観的または楽観的ロックを使用していますか?

私のすべてのクラスには

@バージョン

アノテーションなので、楽観的ロックを使用していると想定しました。

しかし、私がペシミスティックロックを使用していることを示しているように見える私のログの次の例外。どっち? (楽観的ロックを使用したい)

update Song set acoustidFingerprint=?, acoustidId=?, album=?, albumArtist=?, albumArtistSort=?, albumSort=?, amazonId=?, arranger=?, artist=?, artistSort=?, artists=?, barcode=?, bpm=?, catalogNo=?, comment=?, composer=?, composerSort=?, conductor=?, country=?, custom1=?, custom2=?, custom3=?, custom4=?, custom5=?, discNo=?, discSubtitle=?, discTotal=?, djmixer=?, duration=?, encoder=?, engineer=?, fbpm=?, filename=?, genre=?, grouping=?, isCompilation=?, isrc=?, keyOfSong=?, language=?, lastModified=?, lyricist=?, lyrics=?, media=?, mixer=?, mood=?, musicbrainzArtistId=?, musicbrainzDiscId=?, musicbrainzOriginalReleaseId=?, musicbrainzRecordingId=?, musicbrainzReleaseArtistId=?, musicbrainzReleaseCountry=?, musicbrainzReleaseGroupId=?, musicbrainzReleaseId=?, musicbrainzReleaseStatus=?, musicbrainzReleaseType=?, musicbrainzWorkId=?, musicipId=?, occasion=?, originalAlbum=?, originalArtist=?, originalLyricist=?, originalYear=?, producer=?, quality=?, rating=?, recordLabel=?, releaseYear=?, remixer=?, script=?, subtitle=?, tags=?, tempo=?, title=?, titleSort=?, track=?, trackTotal=?, urlDiscogsArtistSite=?, urlDiscogsReleaseSite=?, urlLyricsSite=?, urlOfficialArtistSite=?, urlOfficialReleaseSite=?, urlWikipediaArtistSite=?, urlWikipediaReleaseSite=?, version=? where recNo=? and version=? [50200-172]
**org.hibernate.PessimisticLockException: Timeout trying to lock table ; SQL statement:**
update Song set acoustidFingerprint=?, acoustidId=?, album=?, albumArtist=?, albumArtistSort=?, albumSort=?, amazonId=?, arranger=?, artist=?, artistSort=?, artists=?, barcode=?, bpm=?, catalogNo=?, comment=?, composer=?, composerSort=?, conductor=?, country=?, custom1=?, custom2=?, custom3=?, custom4=?, custom5=?, discNo=?, discSubtitle=?, discTotal=?, djmixer=?, duration=?, encoder=?, engineer=?, fbpm=?, filename=?, genre=?, grouping=?, isCompilation=?, isrc=?, keyOfSong=?, language=?, lastModified=?, lyricist=?, lyrics=?, media=?, mixer=?, mood=?, musicbrainzArtistId=?, musicbrainzDiscId=?, musicbrainzOriginalReleaseId=?, musicbrainzRecordingId=?, musicbrainzReleaseArtistId=?, musicbrainzReleaseCountry=?, musicbrainzReleaseGroupId=?, musicbrainzReleaseId=?, musicbrainzReleaseStatus=?, musicbrainzReleaseType=?, musicbrainzWorkId=?, musicipId=?, occasion=?, originalAlbum=?, originalArtist=?, originalLyricist=?, originalYear=?, producer=?, quality=?, rating=?, recordLabel=?, releaseYear=?, remixer=?, script=?, subtitle=?, tags=?, tempo=?, title=?, titleSort=?, track=?, trackTotal=?, urlDiscogsArtistSite=?, urlDiscogsReleaseSite=?, urlLyricsSite=?, urlOfficialArtistSite=?, urlOfficialReleaseSite=?, urlWikipediaArtistSite=?, urlWikipediaReleaseSite=?, version=? where recNo=? and version=? [50200-172]
    at org.hibernate.dialect.H2Dialect$2.convert(H2Dialect.Java:317)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.Java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.Java:125)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.Java:110)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.Java:129)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.Java:81)
    at com.Sun.proxy.$Proxy22.executeUpdate(Unknown Source)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.Java:3123)
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.Java:3021)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.Java:3350)
    at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.Java:140)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.Java:362)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.Java:354)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.Java:276)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.Java:326)
    at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.Java:62)
    at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.Java:1182)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.Java:1611)
    at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.Java:374)
    at com.jthink.songkong.db.SongCache.loadSongsFromDatabase(SongCache.Java:58)
    at com.jthink.songkong.analyse.analyser.SongGroup.getSongs(SongGroup.Java:48)
    at com.jthink.songkong.analyse.analyser.MergeMusicBrainzMatches.matchToMissingTracks(MergeMusicBrainzMatches.Java:318)
    at com.jthink.songkong.analyse.analyser.MergeMusicBrainzMatches.call(MergeMusicBrainzMatches.Java:105)
    at com.jthink.songkong.analyse.analyser.MergeMusicBrainzMatches.call(MergeMusicBrainzMatches.Java:40)
    at Java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.Java:334)
    at Java.util.concurrent.FutureTask.run(FutureTask.Java:166)
    at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1145)
    at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:615)
    at Java.lang.Thread.run(Thread.Java:722)
Caused by: org.h2.jdbc.JdbcSQLException: Timeout trying to lock table ; SQL statement:
update Song set acoustidFingerprint=?, acoustidId=?, album=?, albumArtist=?, albumArtistSort=?, albumSort=?, amazonId=?, arranger=?, artist=?, artistSort=?, artists=?, barcode=?, bpm=?, catalogNo=?, comment=?, composer=?, composerSort=?, conductor=?, country=?, custom1=?, custom2=?, custom3=?, custom4=?, custom5=?, discNo=?, discSubtitle=?, discTotal=?, djmixer=?, duration=?, encoder=?, engineer=?, fbpm=?, filename=?, genre=?, grouping=?, isCompilation=?, isrc=?, keyOfSong=?, language=?, lastModified=?, lyricist=?, lyrics=?, media=?, mixer=?, mood=?, musicbrainzArtistId=?, musicbrainzDiscId=?, musicbrainzOriginalReleaseId=?, musicbrainzRecordingId=?, musicbrainzReleaseArtistId=?, musicbrainzReleaseCountry=?, musicbrainzReleaseGroupId=?, musicbrainzReleaseId=?, musicbrainzReleaseStatus=?, musicbrainzReleaseType=?, musicbrainzWorkId=?, musicipId=?, occasion=?, originalAlbum=?, originalArtist=?, originalLyricist=?, originalYear=?, producer=?, quality=?, rating=?, recordLabel=?, releaseYear=?, remixer=?, script=?, subtitle=?, tags=?, tempo=?, title=?, titleSort=?, track=?, trackTotal=?, urlDiscogsArtistSite=?, urlDiscogsReleaseSite=?, urlLyricsSite=?, urlOfficialArtistSite=?, urlOfficialReleaseSite=?, urlWikipediaArtistSite=?, urlWikipediaReleaseSite=?, version=? where recNo=? and version=? [50200-172]
    at org.h2.message.DbException.getJdbcSQLException(DbException.Java:329)
    at org.h2.message.DbException.get(DbException.Java:158)
    at org.h2.command.Command.filterConcurrentUpdate(Command.Java:281)
    at org.h2.command.Command.executeUpdate(Command.Java:237)
    at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.Java:154)
    at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.Java:140)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.Java:105)
    at Sun.reflect.GeneratedMethodAccessor55.invoke(Unknown Source)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
    at Java.lang.reflect.Method.invoke(Method.Java:601)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.Java:122)
    ... 24 more
12
Paul Taylor

UPDATEステートメントがすでに示しているように、あなたは 楽観的ロック を使用しています。

where recNo=? and version=?

version列の存在は、楽観的ロックのすべてです。

明示的または暗黙的な行レベルのロック が原因である可能性があるPessimisticLockExceptionに惑わされました。

ダーティライトを回避するために、行のロックが暗黙的に取得されることを理解する必要があります。 この本 は、このトピックを多数の図とコード例で説明しています。

7
Vlad Mihalcea

この例外は、ロックタイムアウトが原因です。

原因:org.h2.jdbc.JdbcSQLException:テーブルをロックしようとしてタイムアウトしました。

ソリューションをチェック ここ

また、hibernateは、アプリケーションに両方のタイプのロックを実装するためのメカニズムを提供します。

ロック戦略は、楽観的でも悲観的でもかまいません。

楽観的

オプティミスティックロックは、複数のトランザクションが互いに影響を与えずに完了できるため、トランザクションが影響を与えるデータリソースをロックせずに続行できることを前提としています。コミットする前に、各トランザクションは、他のトランザクションがデータを変更していないことを確認します。チェックにより競合する変更が明らかになった場合、コミットしたトランザクションはロールバックします[1]。

悲観的

悲観的ロックは、同時トランザクションが互いに競合することを想定しており、リソースが読み込まれた後にロックされ、アプリケーションがデータの使用を終了した後にのみロックが解除されることを必要とします。

詳細はこちら こちら

14
Macrosoft-Dev

LIVE環境とは異なり、テスト用に別のデータベースを使用する可能性があります。

H2はエラーを生成する可能性があり、Oracle、MySQL a.s.o.などのLIVEデータベースには表示されない可能性があります。コードが正しい場合でも、H2が混乱している可能性があります。

MVCC = trueは完全に機能します。同時に、LIVEデータベースの動作を確認するために、ユースケースのLIVEのようなシステムで完全な統合テストがあることを確認する必要があります。

0
user3816944