db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mike Matrigali <mikem_...@sbcglobal.net>
Subject Re: Fwd: Auto generation of database keys
Date Tue, 14 Jun 2005 17:22:44 GMT
I have not been able to reproduce this issue.

Derby uses nested internal transactions when updating the IDENTITY
column, it does not try to guarantee that a value won't be lost.  These
locks should not be held until end of user transaction, they are
committed separate from the user transaction, so the lock is held for
the time it takes to update the system catalog row and commit the
internal transaction.

Is there any chance one of your transactions executed the ddl to
create the table or do any ddl and has not committed?  I assume you
have not set any of the lock timeout properties, it is definitely
possible to block on this lock for a short time so setting locktimeout
to -1 will also cause this issue, but default timeout should not
be happening.

The best 1st step to debugging locking issues is to use the properties
to get the system to dump out more information about the lock table when
you encounter the lock timeout.  Try setting derby.locks.monitor=true.

In this case the interesting information is what locks are being held by
the other transaction
blocking this one.

On a side note, what jvm/derby version are you using.  Getting stack
traces with line numbers can help out a lot in debugging this stuff.
I don't know if I get them because I am using a development build, or
if it is the jvm environment I have.  This should have nothing to do
with the lock timeout, just makes it easier to diagnose the issue.

Craig Russell wrote:

> Hi,
> 
> I'm running into a locking issue when using generated keys. My primary
> key column is defined as DATASTORE_IDENTITY BIGINT NOT NULL GENERATED
> ALWAYS AS IDENTITY. I don't care about the key being transactional. That
> is, if a transaction rolls back, I can live with the key that was
> allocated being permanently unused.
> 
> My application has two transactions inserting rows into the same table,
> and the threads have internal synchronization such that I need to have
> both insert statements succeed independently. The isolation level is the
> default. 
> 
> When I run the transactions, I get a timeout exception indicating that
> only one of the transactions can get an autogenerated key and the other
> has to wait until the first transaction commits. This stack trace is
> from the transaction that is waiting for the first transaction to commit.
> 
>      [java] ERROR 40XL1: A lock could not be obtained within the time
> requested
>      [java]      at
> org.apache.derby.iapi.error.StandardException.newException(StandardExcep
> tion.java)
>      [java]      at
> org.apache.derby.impl.services.locks.LockSet.lockObject(LockSet.java)
>      [java]      at
> org.apache.derby.impl.services.locks.SinglePool.lockAnObject(SinglePool.
> java)
>      [java]      at
> org.apache.derby.impl.services.locks.SinglePool.lockObject(SinglePool.ja
> va)
>      [java]      at
> org.apache.derby.impl.store.raw.xact.RowLocking3.lockRecordForWrite(RowL
> ocking3.java)
>      [java]      at
> org.apache.derby.impl.store.access.conglomerate.OpenConglomerate.lockPos
> itionForWrite(OpenConglomerat
> e.java)
>      [java]      at
> org.apache.derby.impl.store.access.conglomerate.GenericConglomerateContr
> oller.fetch(GenericConglomera
> teController.java)
>      [java]      at
> org.apache.derby.impl.sql.catalog.DataDictionaryImpl.getSetAutoincrement
> Value(DataDictionaryImpl.java
> )
>      [java]      at
> org.apache.derby.impl.sql.execute.InsertResultSet.getSetAutoincrementVal
> ue(InsertResultSet.java)
>      [java]      at
> org.apache.derby.impl.sql.execute.BaseActivation.getSetAutoincrementValu
> e(BaseActivation.java)
>      [java]      at
> org.apache.derby.exe.ac40348015x0104x675cxbca4xffffdab5f0bf0.e0(Unknown
> Source)
>      [java]      at
> org.apache.derby.impl.services.reflect.DirectCall.invoke(ReflectGenerate
> dClass.java)
>      [java]      at
> org.apache.derby.impl.sql.execute.RowResultSet.getNextRowCore(RowResultS
> et.java)
>      [java]      at
> org.apache.derby.impl.sql.execute.NormalizeResultSet.getNextRowCore(Norm
> alizeResultSet.java)
>      [java]      at
> org.apache.derby.impl.sql.execute.DMLWriteResultSet.getNextRowCore(DMLWr
> iteResultSet.java)
>      [java]      at
> org.apache.derby.impl.sql.execute.InsertResultSet.open(InsertResultSet.j
> ava)
>      [java]      at
> org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPrepar
> edStatement.java)
>      [java]      at
> org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatemen
> t.java)
>      [java]      at
> org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(Embed
> PreparedStatement.java)
>      [java]      at
> org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeUpdate(EmbedPre
> paredStatement.java)
>      [java]      at
> org.jpox.store.rdbms.request.Request.executeUpdate(Request.java:69)
>      [java]      at
> org.jpox.store.rdbms.request.InsertRequest.execute(InsertRequest.java:25
> 3)
>      [java]      at
> org.jpox.store.rdbms.table.ClassTable.insert(ClassTable.java:1673)
>      [java]      at
> org.jpox.store.StoreManager.insert(StoreManager.java:634)
>      [java]      at
> org.jpox.state.StateManagerImpl.internalMakePersistent(StateManagerImpl.
> java:2940)
>      [java]      at
> org.jpox.state.StateManagerImpl.makePersistent(StateManagerImpl.java:291
> 3)
> 
> 
> Am I misusing the key generation? Can I get nontransactional key generation?
> 
> Thanks,
> 
> Craig
> 
> Craig Russell
> Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
> 408 276-5638 mailto:Craig.Russell@sun.com
> P.S. A good JDO? O, Gasp!
> 
> 
> Craig Russell
> 
> Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
> 
> 408 276-5638 mailto:Craig.Russell@sun.com
> 
> P.S. A good JDO? O, Gasp!
> 
> 

Mime
View raw message