Skip to content

Commit

Permalink
Clean up around TransactionTerminatedException
Browse files Browse the repository at this point in the history
  • Loading branch information
burqen committed Jun 30, 2016
1 parent cbaf51c commit f0e6805
Show file tree
Hide file tree
Showing 11 changed files with 58 additions and 84 deletions.
Expand Up @@ -19,21 +19,30 @@
*/ */
package org.neo4j.graphdb; package org.neo4j.graphdb;


import static java.util.Objects.requireNonNull; import org.neo4j.kernel.api.exceptions.Status;


/** /**
* Signals that the transaction within which the failed operations ran * Signals that the transaction within which the failed operations ran
* has been terminated with {@link Transaction#terminate()}. * has been terminated with {@link Transaction#terminate()}.
*/ */
public class TransactionTerminatedException extends TransactionFailureException public class TransactionTerminatedException extends TransactionFailureException implements Status.HasStatus
{ {
public TransactionTerminatedException() private final Status status;

public TransactionTerminatedException( Status status )
{
this( status, "" );
}

protected TransactionTerminatedException( Status status, String additionalInfo )
{ {
this( "" ); super( "The transaction has been terminated. " + status.code().description() + " " + additionalInfo );
this.status = status;
} }


public TransactionTerminatedException( String info ) @Override
public Status status()
{ {
super( "The transaction has been terminated. " + requireNonNull( info ) ); return status;
} }
} }
Expand Up @@ -24,6 +24,7 @@
import org.neo4j.graphdb.PropertyContainer; import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.TransactionFailureException; import org.neo4j.graphdb.TransactionFailureException;
import org.neo4j.graphdb.TransactionTerminatedException;
import org.neo4j.graphdb.TransientFailureException; import org.neo4j.graphdb.TransientFailureException;
import org.neo4j.graphdb.TransientTransactionFailureException; import org.neo4j.graphdb.TransientTransactionFailureException;
import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.api.KernelTransaction;
Expand Down Expand Up @@ -86,7 +87,7 @@ public final void finish()
@Override @Override
public final void terminate() public final void terminate()
{ {
this.transaction.markForTermination( Status.Transaction.MarkedAsFailed ); this.transaction.markForTermination( Status.Transaction.Terminated );
} }


@Override @Override
Expand All @@ -110,23 +111,29 @@ public void close()
{ {
throw new ConstraintViolationException( e.getMessage(), e ); throw new ConstraintViolationException( e.getMessage(), e );
} }
catch ( Exception e ) catch ( KernelException | TransactionTerminatedException e )
{ {
String userMessage = successCalled Code statusCode = e.status().code();
? "Transaction was marked as successful, but unable to commit transaction so rolled back." if ( statusCode.classification() == Classification.TransientError )
: "Unable to rollback transaction";
if ( e instanceof KernelException )
{ {
Code statusCode = ((KernelException) e).status().code(); throw new TransientTransactionFailureException(
if ( statusCode.classification() == Classification.TransientError ) closeFailureMessage() + ": " + statusCode.description(), e );
{
throw new TransientTransactionFailureException( userMessage + ": " + statusCode.description(), e );
}
} }
throw new TransactionFailureException( userMessage, e ); throw new TransactionFailureException( closeFailureMessage(), e );
}
catch ( Exception e )
{
throw new TransactionFailureException( closeFailureMessage(), e );
} }
} }


private String closeFailureMessage()
{
return successCalled
? "Transaction was marked as successful, but unable to commit transaction so rolled back."
: "Unable to rollback transaction";
}

@Override @Override
public Lock acquireWriteLock( PropertyContainer entity ) public Lock acquireWriteLock( PropertyContainer entity )
{ {
Expand Down
Expand Up @@ -24,7 +24,6 @@
import java.util.Collections; import java.util.Collections;


import static java.lang.String.format; import static java.lang.String.format;

import static org.neo4j.kernel.api.exceptions.Status.Classification.ClientError; import static org.neo4j.kernel.api.exceptions.Status.Classification.ClientError;
import static org.neo4j.kernel.api.exceptions.Status.Classification.ClientNotification; import static org.neo4j.kernel.api.exceptions.Status.Classification.ClientNotification;
import static org.neo4j.kernel.api.exceptions.Status.Classification.DatabaseError; import static org.neo4j.kernel.api.exceptions.Status.Classification.DatabaseError;
Expand Down Expand Up @@ -123,7 +122,9 @@ enum Transaction implements Status
" and so this transaction was rolled back although it may have looked like it was going to be " + " and so this transaction was rolled back although it may have looked like it was going to be " +
"committed" ), "committed" ),
Outdated( TransientError, "Transaction has seen state which has been invalidated by applied updates while " + Outdated( TransientError, "Transaction has seen state which has been invalidated by applied updates while " +
"transaction was active. Transaction should succeed if retried" ) "transaction was active. Transaction should succeed if retried." ),
LockClientStopped( TransientError, "Lock client is stopped, no more locks can be acquired." ),
Terminated( TransientError, "Explicitly terminated by the user." )
; ;




Expand Down
Expand Up @@ -20,6 +20,7 @@
package org.neo4j.kernel.impl.api; package org.neo4j.kernel.impl.api;


import org.neo4j.graphdb.NotInTransactionException; import org.neo4j.graphdb.NotInTransactionException;
import org.neo4j.graphdb.TransactionTerminatedException;
import org.neo4j.kernel.api.DataWriteOperations; import org.neo4j.kernel.api.DataWriteOperations;
import org.neo4j.kernel.api.ReadOperations; import org.neo4j.kernel.api.ReadOperations;
import org.neo4j.kernel.api.SchemaWriteOperations; import org.neo4j.kernel.api.SchemaWriteOperations;
Expand All @@ -38,8 +39,6 @@
import org.neo4j.kernel.impl.api.store.StoreStatement; import org.neo4j.kernel.impl.api.store.StoreStatement;
import org.neo4j.kernel.impl.locking.Locks; import org.neo4j.kernel.impl.locking.Locks;


import static org.neo4j.kernel.impl.api.TransactionTermination.throwCorrectExceptionBasedOnTerminationReason;

public class KernelStatement implements TxStateHolder, Statement public class KernelStatement implements TxStateHolder, Statement
{ {
protected final Locks.Client locks; protected final Locks.Client locks;
Expand Down Expand Up @@ -132,7 +131,7 @@ void assertOpen()
Status terminationReason = transaction.shouldBeTerminated(); Status terminationReason = transaction.shouldBeTerminated();
if ( terminationReason != null ) if ( terminationReason != null )
{ {
throwCorrectExceptionBasedOnTerminationReason( terminationReason ); throw new TransactionTerminatedException( terminationReason );
} }
} }


Expand Down
Expand Up @@ -544,8 +544,7 @@ private void failOnNonExplicitRollbackIfNeeded() throws TransactionFailureExcept
{ {
if ( success && terminated ) if ( success && terminated )
{ {
String terminationMessage = terminationReason == null ? "" : terminationReason.code().description(); throw new TransactionTerminatedException( terminationReason );
throw new TransactionTerminatedException( terminationMessage );
} }
if ( success ) if ( success )
{ {
Expand Down

This file was deleted.

Expand Up @@ -22,14 +22,13 @@
import org.neo4j.function.Supplier; import org.neo4j.function.Supplier;
import org.neo4j.graphdb.DatabaseShutdownException; import org.neo4j.graphdb.DatabaseShutdownException;
import org.neo4j.graphdb.NotInTransactionException; import org.neo4j.graphdb.NotInTransactionException;
import org.neo4j.graphdb.TransactionTerminatedException;
import org.neo4j.kernel.TopLevelTransaction; import org.neo4j.kernel.TopLevelTransaction;
import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.Statement;
import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.kernel.api.exceptions.Status;
import org.neo4j.kernel.lifecycle.LifecycleAdapter; import org.neo4j.kernel.lifecycle.LifecycleAdapter;


import static org.neo4j.kernel.impl.api.TransactionTermination.throwCorrectExceptionBasedOnTerminationReason;

/** /**
* This is meant to serve as the bridge that makes the Beans API tie transactions to threads. The Beans API * This is meant to serve as the bridge that makes the Beans API tie transactions to threads. The Beans API
* will use this to get the appropriate {@link Statement} when it performs operations. * will use this to get the appropriate {@link Statement} when it performs operations.
Expand Down Expand Up @@ -75,7 +74,7 @@ private void assertInUnterminatedTransaction( TopLevelTransaction transaction )
Status terminationReason = transaction.getTransaction().shouldBeTerminated(); Status terminationReason = transaction.getTransaction().shouldBeTerminated();
if ( terminationReason != null ) if ( terminationReason != null )
{ {
throwCorrectExceptionBasedOnTerminationReason( terminationReason ); throw new TransactionTerminatedException( terminationReason );
} }
} }


Expand Down
Expand Up @@ -20,8 +20,7 @@
package org.neo4j.kernel.impl.locking; package org.neo4j.kernel.impl.locking;


import org.neo4j.graphdb.TransactionTerminatedException; import org.neo4j.graphdb.TransactionTerminatedException;

import org.neo4j.kernel.api.exceptions.Status;
import static java.util.Objects.requireNonNull;


/** /**
* Exception thrown when stopped {@link Locks.Client} used to acquire locks. * Exception thrown when stopped {@link Locks.Client} used to acquire locks.
Expand All @@ -30,6 +29,6 @@ public class LockClientStoppedException extends TransactionTerminatedException
{ {
public LockClientStoppedException( Locks.Client client ) public LockClientStoppedException( Locks.Client client )
{ {
super( requireNonNull( client ) + " is stopped" ); super( Status.Transaction.LockClientStopped, String.valueOf( client ) );
} }
} }
Expand Up @@ -133,7 +133,7 @@ public Void call() throws Exception
} }
catch ( Exception e ) catch ( Exception e )
{ {
assertThat( rootCause( e ), instanceOf( TransientTransactionFailureException.class ) ); assertThat( rootCause( e ), instanceOf( TransactionTerminatedException.class ) );
} }
} }


Expand Down
Expand Up @@ -109,11 +109,11 @@ public void shouldLetThroughTransientFailureException() throws Exception
} }


@Test @Test
public void shouldLetThroughTransactionTerminatedException() throws Exception public void shouldShowTransactionTerminatedExceptionAsTransient() throws Exception
{ {
KernelTransaction kernelTransaction = mock( KernelTransaction.class ); KernelTransaction kernelTransaction = mock( KernelTransaction.class );
doReturn( true ).when( kernelTransaction ).isOpen(); doReturn( true ).when( kernelTransaction ).isOpen();
RuntimeException error = new TransactionTerminatedException(); RuntimeException error = new TransactionTerminatedException( Status.Transaction.Terminated );
doThrow( error ).when( kernelTransaction ).close(); doThrow( error ).when( kernelTransaction ).close();
ThreadToStatementContextBridge bridge = new ThreadToStatementContextBridge(); ThreadToStatementContextBridge bridge = new ThreadToStatementContextBridge();
TopLevelTransaction transaction = new TopLevelTransaction( kernelTransaction, bridge ); TopLevelTransaction transaction = new TopLevelTransaction( kernelTransaction, bridge );
Expand All @@ -126,7 +126,7 @@ public void shouldLetThroughTransactionTerminatedException() throws Exception
} }
catch ( Exception e ) catch ( Exception e )
{ {
assertThat( e, instanceOf( org.neo4j.graphdb.TransactionFailureException.class ) ); assertThat( e, instanceOf( TransientTransactionFailureException.class ) );
assertSame( error, e.getCause() ); assertSame( error, e.getCause() );
} }
} }
Expand Down
Expand Up @@ -19,20 +19,21 @@
*/ */
package org.neo4j.kernel.impl.api.integrationtest; package org.neo4j.kernel.impl.api.integrationtest;


import org.junit.Assert;
import org.junit.Test;

import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;


import org.junit.Assert;
import org.junit.Test;
import org.neo4j.collection.primitive.PrimitiveIntIterator; import org.neo4j.collection.primitive.PrimitiveIntIterator;
import org.neo4j.collection.primitive.PrimitiveLongIterator; import org.neo4j.collection.primitive.PrimitiveLongIterator;
import org.neo4j.function.Function; import org.neo4j.function.Function;
import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.TransactionFailureException; import org.neo4j.graphdb.TransactionFailureException;
import org.neo4j.graphdb.TransientFailureException; import org.neo4j.graphdb.TransactionTerminatedException;
import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.SchemaWriteOperations; import org.neo4j.kernel.api.SchemaWriteOperations;
import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.Statement;
Expand All @@ -44,7 +45,11 @@
import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.concurrent.TimeUnit.SECONDS;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeThat; import static org.junit.Assume.assumeThat;
import static org.neo4j.graphdb.DynamicLabel.label; import static org.neo4j.graphdb.DynamicLabel.label;
import static org.neo4j.helpers.collection.IteratorUtil.asSet; import static org.neo4j.helpers.collection.IteratorUtil.asSet;
Expand Down Expand Up @@ -545,7 +550,7 @@ public void shouldKillTransactionsOnShutdown() throws Throwable
tx.acquireStatement().readOperations().nodeExists( 0l ); tx.acquireStatement().readOperations().nodeExists( 0l );
fail("Should have been terminated."); fail("Should have been terminated.");
} }
catch( TransientFailureException e ) catch( TransactionTerminatedException e )
{ {
// Success // Success
} }
Expand Down

0 comments on commit f0e6805

Please sign in to comment.