[Neo] Estrange exception when running multithreaded

Raul Raja Martinez raulraja at gmail.com
Fri Feb 26 17:21:17 CET 2010


That makes sense, I'll give it a try, thanks!

2010/2/26 Mattias Persson <mattias at neotechnology.com>:
> 2010/2/26 Raul Raja Martinez <raulraja at gmail.com>:
>> Hi Mattias,
>>
>> Thanks for the docs.
>> I'm trying to solve this issue now and here is the problem I'm facing...
>>
>> Where it says in the wiki:
>> "Rewrite your code, making sure that such scenarios won't happen.
>> Run your deadlock-prone code in a try-catch(DeadlockDetectedException)
>> block and just rerun the entire transaction if such an exception is
>> caught."
>>
>> My transactions start and end in an interceptor that provides advice
>> to method invokations.
>> The invokations happen inside a thread pool concurrently.
>>
>> This is what the interceptor looks like. I have no way to recover from
>> the deadlock. Are you implying in that advice that
>> I should synchronize in the operation that is causing the write lock?
>> Is there anyway to configure Neo to wait on deadlock for a release up
>> to certain time?
>> If I reissue a method call that is transactional other state not
>> related to the neo transactions such as indexes, etc... may modify
>> other state objects, I'd rather have the transaction wait for release
>> and continue as other transactions are completing.
> To make the executing thread wait would result in a deadlock, that's
> why the exception is thrown so that isn't really an option.
>
> Regarding state: if you're referring to components in neo4j, they all
> handle state correctly if a transaction is rolled back (in this case
> where a DeadlockDetectedException is thrown)... even the IndexService
> and such components so that won't be a problem.
>>
>> Here is the code for the interceptor. The advised methods are
>> Runnables that get executed async by a threadpool.
>>
>> /**
>>  * A method interceptor that provides transaction advice around a
>> method invocation opening and closing a transaction accordingly
>>  */
>> public class Neo4JTransactionAdviceInterceptor implements MethodInterceptor {
>>
>>    private final static Logger log =
>> Logger.getLogger(Neo4JTransactionAdviceInterceptor.class);
>>
>>    private GraphDatabaseService neoService;
>>
>>    public void setNeoService(GraphDatabaseService neoService) {
>>        this.neoService = neoService;
>>    }
>>
>>    /**
>>     * provides transaction advice around a method invocation opening
>> and closing a transaction accordingly
>>     *
>>     * @param invocation the method invocation joinpoint
>>     * @return the result of the call to {@link
>>     *         org.aopalliance.intercept.Joinpoint#proceed()}, might
>> be intercepted by the
>>     *         interceptor.
>>     * @throws Throwable if the interceptors or the
>>     *                   target-object throws an exception.
>>     */
>>    public Object invoke(MethodInvocation invocation) throws Throwable {
>>        Transaction tx = neoService.beginTx();
>>        Object result = null;
>>                try {
>>                        result = invocation.proceed();
>>                        tx.success();
>>                } catch (DeadlockDetectedException e) {
>>            tx.failure();
>>            log.debug("deadlock detected for invocation " + invocation
>> + " result: " + result + " transaction: " + tx);
>>        } catch (Throwable t) {
>>                        tx.failure();
>>            throw t;
>>                } finally {
>>                        tx.finish();
>>                }
>>        return result;
>>    }
>> }
>>
>>
>
> How about making your code look something like (I removed unecessary
> tx.failure() calls, see
> http://wiki.neo4j.org/content/Transactions#Controlling_success):
>
> public Object invoke(MethodInvocation invocation) throws Throwable {
>    Object result = null;
>    for ( int i = 0; i < 10; i++ ) {
>        Transaction tx = neoService.beginTx();
>        try {
>            result = invocation.proceed();
>            tx.success();
>            return result;
>        } catch (DeadlockDetectedException e) {
>            log.debug("deadlock detected for invocation " + invocation
>                + " result: " + result + " transaction: " + tx);
>        } finally {
>            tx.finish();
>        }
>    }
>    return result;
> }
>
> Where 10 is the number of retries to do before giving up. It may not
> look very elegant, but there's really no "silver bullet" for the the
> deadlock problem.
>
> --
> Mattias Persson, [mattias at neotechnology.com]
> Neo Technology, www.neotechnology.com
> _______________________________________________
> Neo mailing list
> User at lists.neo4j.org
> https://lists.neo4j.org/mailman/listinfo/user
>



-- 
Raul Raja


More information about the User mailing list