Andrey,

The fix to Issue 1977 does work to fix this bug.

Is there any chance that we could get this on a hotfix?

Steve

On Friday, January 17, 2014 11:03:21 PM UTC-7, StevenTomer wrote:
>
> We are getting the server into a bad state, after which every transaction 
> fails with a java.lang.Error (Maximum lock count exceeded).  We're using a 
> remote connection.
>
> I wrapped a try block, around the lock.readLock().lock() call in the class 
> OModificationLock, checking for java.lang.Error (and printing a stack trace 
> if there is a failure) and adding an instance counter.
>
> I found that there is a path for which calls to requestModificationLock 
> are not being followed up by calls to releaseModificationLock.
>
> The Maximum lock count exceeded message occurs around when the counter 
> reaches ~520,000.
>
> When I get the error, the stack trace I printed is as follows:
> java.lang.Error (Maximum lock count exceeded)
> com.orientechnologies.common.concur.lock.OModificationLock.
> requestMoficationLock(OModificationLock.java:51)
> com.orientechnologies.orient.core.index.OIndexAbstract.
> acquireModificationLock(OIndexAbstract.java:1084)
> com.orientechnologies.orient.core.index.OClassIndexManager.
> acquireModificationLock(OClassIndexManager.java:556)
> com.orientechnologies.orient.core.index.OClassIndexManager.
> checkIndexesAndAcquireLock(OClassIndexManager.java:522)
> com.orientechnologies.orient.core.index.OClassIndexManager.
> onRecordBeforeUpdate(OClassIndexManager.java:129)
> com.orientechnologies.orient.core.hook.ODocumentHookAbstract.onTrigger(
> ODocumentHookAbstract.java:263)
> com.orientechnologies.orient.core.db.record.ODatabaseRecordAbstract.
> callbackHooks(ODatabaseRecordAbstract.java:1065)
> com.orientechnologies.orient.core.tx.OTransactionOptimistic.addRecord(
> OTransactionOptimistic.java:313)
> com.orientechnologies.orient.server.tx.OTransactionOptimisticProxy.begin(
> OTransactionOptimisticProxy.java:129)
> com.orientechnologies.orient.core.db.record.ODatabaseRecordTx.begin(
> ODatabaseRecordTx.java:94)
> com.orientechnologies.orient.core.db.record.ODatabaseRecordTx.begin(
> ODatabaseRecordTx.java:38)
> com.orientechnologies.orient.core.db.ODatabaseRecordWrapperAbstract.begin(
> ODatabaseRecordWrapperAbstract.java:126)
> com.orientechnologies.orient.server.network.protocol.binary.
> ONetworkProtocolBinary.commit(ONetworkProtocolBinary.java:1047)
> com.orientechnologies.orient.server.network.protocol.binary.
> ONetworkProtocolBinary.executeRequest(ONetworkProtocolBinary.java:303)
> com.orientechnologies.orient.server.network.protocol.binary.
> OBinaryNetworkProtocolAbstract.execute(OBinaryNetworkProtocolAbstract.java
> :125)
> com.orientechnologies.common.thread.OSoftThread.run(OSoftThread.java:45)
>
>
>
> Tracing into the problem, it only occurs for us when sending a 
> Transaction, and the number of locks only increases for creates in this 
> transaction (not for updates...)
>
> (OTransactionOptimistic.java)
> protected void addRecord(final ORecordInternal<?> iRecord, final byteiStatus
> , final String iClusterName) {
>     switch (iStatus) {
>         case ORecordOperation.CREATED:
>             database.checkSecurity(ODatabaseSecurityResources.CLUSTER, 
> ORole.PERMISSION_CREATE, iClusterName);
>             // !! This gets the Modification Lock !!
>             database.callbackHooks(TYPE.BEFORE_CREATE, iRecord); 
>     break;
>
>
>     ...
>
>
>     switch (iStatus) {
>         case ORecordOperation.CREATED:
>             // !! This calls the hooks that apply after a create, which 
> should free the Modification Lock !!
>             database.callbackHooks(TYPE.AFTER_CREATE, iRecord);  
>             break;
>
>
>     ...
>
>
> (ODatabaseRecordAbstract.java)
> public ORecordHook.RESULT callbackHooks(final TYPE iType, final 
> OIdentifiable id) {
>     // !! There are some returns at the beginning of this function that 
> may not be safe - won't free the lock !!
>     ...
>     // !! Call the trigger !!
>     final RESULT res = hook.onTrigger(iType, rec);
>     ...
>
>
> (ODocumentHookAbstract.java)
> public RESULT onTrigger(final TYPE iType, final ORecord<?> iRecord) {
>     if (ODatabaseRecordThreadLocal.INSTANCE.isDefined() && 
> ODatabaseRecordThreadLocal.INSTANCE.get().getStatus() != STATUS.OPEN)
>         // !! Probably not safe - won't free the lock !!
>         return RESULT.RECORD_NOT_CHANGED;
>
>
>     if (!(iRecord instanceof ODocument))
>         // !! Probably not safe - won't free the lock !!
>         return RESULT.RECORD_NOT_CHANGED;
>
>
>     final ODocument document = (ODocument) iRecord;
>     if (!filterBySchemaClass(document))
>         // !! Not safe - won't free the lock !!
>         // !! The creates are falling in here when iType = 
> TYPE.AFTER_CREATE !!
>         return RESULT.RECORD_NOT_CHANGED;
>     ...
>
>
>     switch (iType) {
>         case AFTER_CREATE:
>             // !! releases the lock - we don't get here !!
>             onRecordAfterCreate(document);
>             break;
>         case CREATE_FAILED:
>             // !! releases the lock - we don't get here !!
>             onRecordCreateFailed(document);
>             break;
>     ...
>
>
> It seems to me that filterBySchemaClass is not doing the right thing - the 
> variable includeClasses is set, but only with single items like OFunction 
> or OUser.  I don't think this is how it was intended to be used.
>
> The return statements that don't call the hook also seem like a problem. 
>  Maybe it would be wise to look into whether the return statements are the 
> right strategy, considering the implications of not releasing the locks. 
>  It looks like it is possible to get into a similar situation with Updates 
> or Deletes, although we have not yet experienced it.
>
> We're really in a bind with this problem - we don't want to have to 
> downgrade back to the 1.1.0 server we have been using.
>
> Thanks for your help.  I hope I've given you enough information to put you 
> right on it.  I've made issue 1977 for this.
>
> Steve
>
>
>

-- 

--- 
You received this message because you are subscribed to the Google Groups 
"OrientDB" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to