我所有的课程都有
@Version
注释,所以我假设他们使用乐观锁定。
但是我的日志中的以下异常似乎表明我使用了悲观锁定。那是哪个呢? (我想使用乐观锁定)
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
答案 0 :(得分:12)
此异常是由Lock TimeOut引起的。
引起:org.h2.jdbc.JdbcSQLException:超时试图锁定表; 的
检查解决方案here
hibernate还提供了在应用程序中实现这两种锁定的机制。
您的锁定策略可能是乐观的,也可能是悲观的。
乐观
可以完成多个事务而不会相互影响的乐观锁定,因此事务可以在不锁定它们影响的数据资源的情况下继续进行。在提交之前,每个事务都会验证没有其他事务已修改其数据。如果检查显示有相互矛盾的修改,则提交事务将回滚[1]。
悲观
悲观锁定假定并发事务将相互冲突,并且需要在读取资源后锁定资源,并且仅在应用程序使用完数据后解锁。
可以找到详细信息here
答案 1 :(得分:6)
您正在使用optimistic locking,因为您的UPDATE
语句已经表明:
where recNo=? and version=?
version
列的存在是乐观锁定的全部内容。
您被PessimisticLockException
误导,可能是由explicit or an implicit row-level lock造成的。
您必须了解隐式获取行的锁,以避免脏写。 This book通过大量的图表和代码示例解释了这个主题。
答案 2 :(得分:0)
最有可能的是,您将使用不同的数据库进行测试,而不是在LIVE环境中使用。
H2可能会产生错误,这可能不会出现在LIVE数据库中,例如Oracle,MySQL a.s.o ..意味着即使你的代码是正确的,但H2可能会搞乱。
MVCC = true完美无缺。 同时,您应确保对用例的LIVE系统进行完全集成测试,以验证LIVE数据库的行为。