Skip to content

Commit

Permalink
Merge pull request #340 from lutovich/1.2-reset-tx-func
Browse files Browse the repository at this point in the history
Fix reset of transaction functions
  • Loading branch information
Zhen Li authored Mar 23, 2017
2 parents bec13b3 + b40e53a commit 6a9cab3
Show file tree
Hide file tree
Showing 4 changed files with 463 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ public synchronized void onConnectionError( boolean recoverable )
}
}

private synchronized <T> T transaction( AccessMode mode, TransactionWork<T> work )
private <T> T transaction( AccessMode mode, TransactionWork<T> work )
{
RetryDecision decision = null;
List<Throwable> errors = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,25 @@ private static boolean canRetryOn( Throwable error )
{
return error instanceof SessionExpiredException ||
error instanceof ServiceUnavailableException ||
error instanceof TransientException;
isTransientError( error );
}

private static boolean isTransientError( Throwable error )
{
if ( error instanceof TransientException )
{
String code = ((TransientException) error).code();
// Retries should not happen when transaction was explicitly terminated by the user.
// Termination of transaction might result in two different error codes depending on where it was
// terminated. These are really client errors but classification on the server is not entirely correct and
// they are classified as transient.
if ( "Neo.TransientError.Transaction.Terminated".equals( code ) ||
"Neo.TransientError.Transaction.LockClientStopped".equals( code ) )
{
return false;
}
return true;
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,32 @@ public void sleepsOnTransientException() throws Exception
verify( clock ).sleep( 1 );
}

@Test
public void doesNothingWhenTransactionTerminatedError() throws Exception
{
Clock clock = mock( Clock.class );
ExponentialBackoff backoff = newBackoff( 1, 1, 1, 0, clock );

TransientException exception = new TransientException( "Neo.TransientError.Transaction.Terminated", "" );
ExponentialBackoffDecision decision = backoff.apply( exception, null );

assertFalse( decision.shouldRetry() );
verify( clock, never() ).sleep( anyLong() );
}

@Test
public void doesNothingWhenTransactionLockClientStoppedError() throws Exception
{
Clock clock = mock( Clock.class );
ExponentialBackoff backoff = newBackoff( 1, 1, 1, 0, clock );

TransientException exception = new TransientException( "Neo.TransientError.Transaction.LockClientStopped", "" );
ExponentialBackoffDecision decision = backoff.apply( exception, null );

assertFalse( decision.shouldRetry() );
verify( clock, never() ).sleep( anyLong() );
}

@Test
public void throwsWhenSleepInterrupted() throws Exception
{
Expand Down
Loading

0 comments on commit 6a9cab3

Please sign in to comment.