Concurrent access with FILE_LOCK=SERIALIZED

151 views
Skip to first unread message

LRichard

unread,
Dec 13, 2011, 2:07:46 PM12/13/11
to h2-da...@googlegroups.com
Hello,

   We get the following exception when stressing a database from two different processes with FILE_LOCK=SERIALIZED

Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not get next sequence value
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387)
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1315)
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1321)
        at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:843)
        at fr.harvest.big.dao.BigDao.create(BigDao.java:217)
        at fr.harvest.big.direct.BigPersistDirect.putEntity(BigPersistDirect.java:193)
        at fr.harvest.big.direct.BigPersistDirect.putSession(BigPersistDirect.java:315)
        at fr.harvest.big.common.BigPersist.acquireSession(BigPersist.java:250)
Caused by: org.hibernate.exception.GenericJDBCException: could not get next sequence value
        at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140)
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:128)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
        at org.hibernate.id.SequenceGenerator.generateHolder(SequenceGenerator.java:132)
        at org.hibernate.id.SequenceHiLoGenerator.generate(SequenceHiLoGenerator.java:78)
        at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
        at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:69)
        at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:179)
        at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135)
        at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:61)
        at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:808)
        at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:782)
        at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:786)
        at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:837)
        ... 4 more
Caused by: org.h2.jdbc.JdbcSQLException: General error: "java.lang.RuntimeException: Unexpected code path" [50000-161]
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
        at org.h2.message.DbException.get(DbException.java:158)
        at org.h2.message.DbException.convert(DbException.java:281)
        at org.h2.message.DbException.toSQLException(DbException.java:254)
        at org.h2.message.TraceObject.logAndConvert(TraceObject.java:368)
        at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:104)
        at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
        at org.hibernate.id.SequenceGenerator.generateHolder(SequenceGenerator.java:112)
        ... 14 more
Caused by: java.lang.RuntimeException: Unexpected code path
        at org.h2.message.DbException.throwInternalError(DbException.java:228)
        at org.h2.message.DbException.throwInternalError(DbException.java:241)
        at org.h2.engine.Database.afterWriting(Database.java:2269)
        at org.h2.command.Command.executeQuery(Command.java:199)
        at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:96)
        ... 16 more

As far as I can understand it, the H2 engine is executing some code that should never be reached.
    public void afterWriting() {
        if (fileLockMethod != FileLock.LOCK_SERIALIZED) {
            return;
        }
        synchronized (reconnectSync) {
            checkpointAllowed--;
        }
        if (SysProperties.CHECK && checkpointAllowed < 0) {
            throw DbException.throwInternalError();
        }
    }

I was wondering if it wouldn't be safer to check the checkpointAllowed field inside the synchronized section but this may not be the explanation.

We're trying to get some sample code to reproduce without our whole application (which uses hibernate, c3p0, ...) in order to provide it.
However, meanwhile, any help on that topic would be much appreciated.

Thomas Mueller

unread,
Dec 18, 2011, 12:54:22 PM12/18/11
to h2-da...@googlegroups.com
Hi,

> As far as I can understand it, the H2 engine is executing some code that should never be reached.

Yes, that's true.

> We're trying to get some sample code to reproduce without our whole application

That would be great!

Regards,
Thomas

LRichard

unread,
Dec 26, 2011, 12:33:46 PM12/26/11
to h2-da...@googlegroups.com
Hi,

We didn't manage to reproduce with some simple code yet. I think we'll give up this search since we'll focus our attention on the mixed mode now.

Regards,
Laurent
Reply all
Reply to author
Forward
0 new messages