Skip to content

Commit

Permalink
Add possibility to start particular transaction with custom timeout.
Browse files Browse the repository at this point in the history
Restore possibility to specify custom timeout for transaction started by cypher rest endpoint.
  • Loading branch information
MishaDemianenko committed Aug 16, 2016
1 parent 7544371 commit 8e98128
Show file tree
Hide file tree
Showing 11 changed files with 263 additions and 125 deletions.
Expand Up @@ -28,8 +28,8 @@
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.security.URLAccessValidationError;
import org.neo4j.kernel.GraphDatabaseQueryService;
import org.neo4j.kernel.api.security.AccessMode;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.security.AccessMode;
import org.neo4j.kernel.impl.coreapi.InternalTransaction;
import org.neo4j.kernel.impl.factory.GraphDatabaseFacade;

Expand Down Expand Up @@ -78,6 +78,13 @@ public InternalTransaction beginTransaction( KernelTransaction.Type type, Access
return graph.beginTransaction( type, accessMode );
}

@Override
public InternalTransaction beginTransaction( KernelTransaction.Type type, AccessMode accessMode,
long timeout )
{
return graph.beginTransaction( type, accessMode, timeout );
}

@Override
public URL validateURLAccess( URL url ) throws URLAccessValidationError
{
Expand Down
Expand Up @@ -26,8 +26,8 @@
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.security.URLAccessValidationError;
import org.neo4j.kernel.api.security.AccessMode;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.security.AccessMode;
import org.neo4j.kernel.impl.coreapi.InternalTransaction;

/*
Expand All @@ -41,6 +41,10 @@ public interface GraphDatabaseQueryService
Node createNode( Label... labels );
Node getNodeById(long id);
Relationship getRelationshipById(long id);

InternalTransaction beginTransaction( KernelTransaction.Type type, AccessMode accessMode );

InternalTransaction beginTransaction( KernelTransaction.Type implicit, AccessMode accessMode, long timeout );

URL validateURLAccess( URL url ) throws URLAccessValidationError;
}
Expand Up @@ -40,10 +40,21 @@ public interface KernelAPI
* underlying graph.
*
* @param type the type of the new transaction: implicit (internally created) or explicit (created by the user)
* @param accessMode
* @param accessMode transaction access mode
*/
KernelTransaction newTransaction( KernelTransaction.Type type, AccessMode accessMode ) throws TransactionFailureException;

/**
* Creates and returns a new {@link KernelTransaction} capable of modifying the
* underlying graph.
*
* @param type the type of the new transaction: implicit (internally created) or explicit (created by the user)
* @param accessMode transaction access mode
* @param timeout transaction timeout
*/
KernelTransaction newTransaction( KernelTransaction.Type type, AccessMode accessMode, long timeout )
throws TransactionFailureException;

/**
* Registers a {@link TransactionHook} that will receive notifications about committing transactions
* and the changes they commit.
Expand Down
Expand Up @@ -87,9 +87,16 @@ public Kernel( KernelTransactions transactionFactory, TransactionHooks hooks, Da

@Override
public KernelTransaction newTransaction( KernelTransaction.Type type, AccessMode accessMode ) throws TransactionFailureException
{
return newTransaction( type, accessMode, defaultTransactionTimeout );
}

@Override
public KernelTransaction newTransaction( KernelTransaction.Type type, AccessMode accessMode, long timeout )
throws TransactionFailureException
{
health.assertHealthy( TransactionFailureException.class );
KernelTransaction transaction = transactions.newInstance( type, accessMode, defaultTransactionTimeout );
KernelTransaction transaction = transactions.newInstance( type, accessMode, timeout );
transactionMonitor.transactionStarted();
return transaction;
}
Expand Down
Expand Up @@ -28,13 +28,14 @@
import org.neo4j.graphdb.Result;
import org.neo4j.graphdb.event.KernelEventHandler;
import org.neo4j.graphdb.event.TransactionEventHandler;
import org.neo4j.graphdb.factory.GraphDatabaseSettings;
import org.neo4j.graphdb.security.URLAccessValidationError;
import org.neo4j.kernel.GraphDatabaseQueryService;
import org.neo4j.kernel.api.security.AccessMode;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.Statement;
import org.neo4j.kernel.api.exceptions.TransactionFailureException;
import org.neo4j.kernel.api.legacyindex.AutoIndexing;
import org.neo4j.kernel.api.security.AccessMode;
import org.neo4j.kernel.impl.coreapi.CoreAPIAvailabilityGuard;
import org.neo4j.kernel.impl.query.QueryExecutionKernelException;
import org.neo4j.kernel.impl.query.QuerySession;
Expand All @@ -53,13 +54,15 @@ class ClassicCoreSPI implements GraphDatabaseFacade.SPI
private final DataSourceModule dataSource;
private final Logger msgLog;
private final CoreAPIAvailabilityGuard availability;
private final long defaultTransactionTimeout;

public ClassicCoreSPI(PlatformModule platform, DataSourceModule dataSource, Logger msgLog, CoreAPIAvailabilityGuard availability )
{
this.platform = platform;
this.dataSource = dataSource;
this.msgLog = msgLog;
this.availability = availability;
defaultTransactionTimeout = platform.config.get( GraphDatabaseSettings.transaction_timeout );
}

@Override
Expand Down Expand Up @@ -166,11 +169,17 @@ public void shutdown()

@Override
public KernelTransaction beginTransaction( KernelTransaction.Type type, AccessMode accessMode )
{
return beginTransaction( type, accessMode, defaultTransactionTimeout );
}

@Override
public KernelTransaction beginTransaction( KernelTransaction.Type type, AccessMode accessMode, long timeout )
{
try
{
availability.assertDatabaseAvailable();
KernelTransaction kernelTx = dataSource.kernelAPI.get().newTransaction( type, accessMode );
KernelTransaction kernelTx = dataSource.kernelAPI.get().newTransaction( type, accessMode, timeout );
kernelTx.registerCloseListener( (s) -> dataSource.threadToTransactionBridge.unbindTransactionFromCurrentThread() );
dataSource.threadToTransactionBridge.bindTransactionToCurrentThread( kernelTx );
return kernelTx;
Expand Down
Expand Up @@ -23,6 +23,7 @@
import java.net.URL;
import java.util.Collections;
import java.util.Map;
import java.util.function.Supplier;

import org.neo4j.collection.primitive.PrimitiveLongCollections;
import org.neo4j.collection.primitive.PrimitiveLongIterator;
Expand Down Expand Up @@ -147,6 +148,16 @@ public interface SPI
*/
KernelTransaction beginTransaction( KernelTransaction.Type type, AccessMode accessMode );

/**
* Begin a new kernel transaction with specified timeout.
* If a transaction is already associated to the current context
* (meaning, non-null is returned from {@link #currentTransaction()}), this should fail.
*
* @throws org.neo4j.graphdb.TransactionFailureException if unable to begin, or a transaction already exists.
* @see SPI#beginTransaction(KernelTransaction.Type, AccessMode)
*/
KernelTransaction beginTransaction( KernelTransaction.Type type, AccessMode accessMode, long timeout );

/**
* Retrieve the transaction associated with the current context. For the classic implementation of the Core API,
* the context is the current thread.
Expand Down Expand Up @@ -333,19 +344,19 @@ public Transaction beginTx()

public InternalTransaction beginTransaction( KernelTransaction.Type type, AccessMode accessMode )
{
if ( spi.isInOpenTransaction() )
{
// FIXME: perhaps we should check that the new type and access mode are compatible with the current tx
return new PlaceboTransaction( spi::currentTransaction, spi::currentStatement );
}
return beginTransaction( () -> spi.beginTransaction( type, accessMode ) );
}

return new TopLevelTransaction( spi.beginTransaction( type, accessMode ), spi::currentStatement );
public InternalTransaction beginTransaction( KernelTransaction.Type type, AccessMode accessMode,
long timeout )
{
return beginTransaction( () -> spi.beginTransaction( type, accessMode, timeout ) );
}

@Override
public Result execute( String query ) throws QueryExecutionException
{
return execute( query, Collections.<String,Object>emptyMap() );
return execute( query, Collections.emptyMap() );
}

@Override
Expand Down Expand Up @@ -403,6 +414,7 @@ public ResourceIterable<RelationshipType> getAllRelationshipTypesInUse()
{
return allInUse( TokenAccess.RELATIONSHIP_TYPES );
}

private <T> ResourceIterable<T> allInUse( final TokenAccess<T> tokens )
{
assertTransactionOpen();
Expand Down Expand Up @@ -495,6 +507,16 @@ public ResourceIterator<Node> findNodes( final Label myLabel )
return allNodesWithLabel( myLabel );
}

private InternalTransaction beginTransaction( Supplier<KernelTransaction> transactionSupplier )
{
if ( spi.isInOpenTransaction() )
{
// FIXME: perhaps we should check that the new type and access mode are compatible with the current tx
return new PlaceboTransaction( spi::currentTransaction, spi::currentStatement );
}
return new TopLevelTransaction( transactionSupplier.get(), spi::currentStatement );
}

private ResourceIterator<Node> nodesByLabelAndProperty( Label myLabel, String key, Object value )
{
Statement statement = spi.currentStatement();
Expand Down
Expand Up @@ -200,4 +200,10 @@ public KernelTransaction beginTransaction( KernelTransaction.Type type, AccessMo
{
throw new UnsupportedOperationException();
}

@Override
public KernelTransaction beginTransaction( KernelTransaction.Type type, AccessMode accessMode, long timeout )
{
throw new UnsupportedOperationException();
}
}

0 comments on commit 8e98128

Please sign in to comment.