Skip to content

Commit

Permalink
Allow to start transaction with custom timeout from GraphDatabaseFacade.
Browse files Browse the repository at this point in the history
Rename property for timeout of idle transactions in the REST endpoint from 'dbms.transaction_timeout' to 'dbms.rest.transaction.idle_timeout'.
  • Loading branch information
MishaDemianenko committed Sep 7, 2016
1 parent 3165dab commit 67ed213
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 23 deletions.
Expand Up @@ -237,6 +237,22 @@ public interface GraphDatabaseService
*/
Transaction beginTx();

/**
* Starts a new {@link Transaction transaction} with custom timeout and associates it with the current thread.
* Timeout will be taken into account <b>only</b> when execution guard is enabled.
* <p>
* <em>All database operations must be wrapped in a transaction.</em>
* <p>
* If you attempt to access the graph outside of a transaction, those operations will throw
* {@link NotInTransactionException}.
* <p>
* Please ensure that any returned {@link ResourceIterable} is closed correctly and as soon as possible
* inside your transaction to avoid potential blocking of write operations.
*
* @return a new transaction instance
*/
Transaction beginTx( long timeout );

/**
* Executes a query and returns an iterable that contains the result set.
*
Expand Down
Expand Up @@ -343,6 +343,12 @@ public Transaction beginTx()
return beginTransaction( KernelTransaction.Type.explicit, AccessMode.Static.FULL );
}

@Override
public Transaction beginTx( long timeout )
{
return beginTransaction( KernelTransaction.Type.explicit, AccessMode.Static.FULL, timeout );
}

public InternalTransaction beginTransaction( KernelTransaction.Type type, AccessMode accessMode )
{
return beginTransaction( () -> spi.beginTransaction( type, accessMode ) );
Expand Down
Expand Up @@ -147,6 +147,12 @@ public Transaction beginTx()
return getGraphDatabaseAPI().beginTx();
}

@Override
public Transaction beginTx( long timeout)
{
return getGraphDatabaseAPI().beginTx( timeout );
}

@Override
public Node createNode( Label... labels )
{
Expand Down
Expand Up @@ -265,7 +265,7 @@ private TransactionFacade createTransactionalActions()
*/
private long getTransactionTimeoutMillis()
{
final long timeout = config.get( ServerSettings.transaction_timeout );
final long timeout = config.get( ServerSettings.transaction_idle_timeout );
return Math.max( timeout, MINIMUM_TIMEOUT + ROUNDING_SECOND );
}

Expand Down
Expand Up @@ -232,7 +232,7 @@ private ThirdPartyJaxRsPackage createThirdPartyJaxRsPackage( String packageAndMo
Setting<File> lib_directory = pathSetting( "dbms.directories.lib", "lib" );

@Description("Timeout for idle transactions in the REST endpoint.")
Setting<Long> transaction_timeout = setting( "dbms.transaction_timeout", DURATION, "60s" );
Setting<Long> transaction_idle_timeout = setting( "dbms.rest.transaction.idle_timeout", DURATION, "60s" );

@Internal
Setting<URI> rest_api_path = setting( "unsupported.dbms.uris.rest", NORMALIZED_RELATIVE_URI, "/db/data" );
Expand Down
Expand Up @@ -19,12 +19,12 @@
*/
package org.neo4j.server;

import java.util.List;
import java.util.Map;

import org.junit.After;
import org.junit.Test;

import java.util.List;
import java.util.Map;

import org.neo4j.server.configuration.ServerSettings;
import org.neo4j.test.server.ExclusiveServerTestBase;
import org.neo4j.test.server.HTTP;
Expand All @@ -50,7 +50,7 @@ public void stopTheServer()
public void shouldHonorReallyLowSessionTimeout() throws Exception
{
// Given
server = server().withProperty( ServerSettings.transaction_timeout.name(), "1" ).build();
server = server().withProperty( ServerSettings.transaction_idle_timeout.name(), "1" ).build();
server.start();

String tx = HTTP.POST( txURI(), asList( map( "statement", "CREATE (n)" ) ) ).location();
Expand All @@ -62,7 +62,7 @@ public void shouldHonorReallyLowSessionTimeout() throws Exception
// Then
@SuppressWarnings("unchecked")
List<Map<String, Object>> errors = (List<Map<String, Object>>) response.get( "errors" );
assertThat( (String) errors.get( 0 ).get( "code" ), equalTo( TransactionNotFound.code().serialize() ) );
assertThat( errors.get( 0 ).get( "code" ), equalTo( TransactionNotFound.code().serialize() ) );
}

private String txURI()
Expand Down
Expand Up @@ -48,7 +48,7 @@ public class ExtensionInitializerTest
@Test
public void testPluginInitialization()
{
Config config = new Config( stringMap( ServerSettings.transaction_timeout.name(), "600" ) );
Config config = new Config( stringMap( ServerSettings.transaction_idle_timeout.name(), "600" ) );
NeoServer neoServer = Mockito.mock( NeoServer.class, Mockito.RETURNS_DEEP_STUBS );
Mockito.when( neoServer.getConfig() ).thenReturn( config );
ExtensionInitializer extensionInitializer = new ExtensionInitializer( neoServer );
Expand All @@ -58,7 +58,7 @@ public void testPluginInitialization()

assertThat( injectableProperties, Matchers.hasSize( 1 ) );
assertThat( injectableProperties, Matchers.contains( new InjectableMatcher<>( ServerSettings
.transaction_timeout.name() ) ) );
.transaction_idle_timeout.name() ) ) );
}

private class InjectableMatcher<T> extends BaseMatcher<Injectable<?>>
Expand Down
Expand Up @@ -19,17 +19,16 @@
*/
package org.neo4j.server.plugins;

import org.junit.Test;

import java.net.URI;
import java.util.HashMap;

import org.junit.Test;

import org.neo4j.kernel.configuration.Config;
import org.neo4j.server.configuration.ServerSettings;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import static org.neo4j.helpers.collection.MapUtil.stringMap;

public class ConfigAdapterTest
Expand Down Expand Up @@ -82,15 +81,15 @@ public void shouldAbleToAccessRegisteredPropertyByName()
Config config = new Config( new HashMap<>(), ServerSettings.class );
ConfigAdapter wrappingConfiguration = new ConfigAdapter( config );

assertEquals( 60000L, wrappingConfiguration.getProperty( ServerSettings.transaction_timeout.name() ) );
assertEquals( 60000L, wrappingConfiguration.getProperty( ServerSettings.transaction_idle_timeout.name() ) );
}

@Test
public void shouldAbleToAccessNonRegisteredPropertyByName()
{
Config config = new Config( stringMap( ServerSettings.transaction_timeout.name(), "600" ) );
Config config = new Config( stringMap( ServerSettings.transaction_idle_timeout.name(), "600" ) );
ConfigAdapter wrappingConfiguration = new ConfigAdapter( config );

assertEquals( "600", wrappingConfiguration.getProperty( ServerSettings.transaction_timeout.name() ) );
assertEquals( "600", wrappingConfiguration.getProperty( ServerSettings.transaction_idle_timeout.name() ) );
}
}
Expand Up @@ -59,8 +59,8 @@
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.security.AccessMode;
import org.neo4j.kernel.impl.coreapi.InternalTransaction;
import org.neo4j.kernel.internal.GraphDatabaseAPI;
import org.neo4j.kernel.impl.store.StoreId;
import org.neo4j.kernel.internal.GraphDatabaseAPI;

public class ReadOnlyGraphDatabaseProxy implements GraphDatabaseService, GraphDatabaseAPI, IndexManager
{
Expand Down Expand Up @@ -103,10 +103,16 @@ public Transaction beginTx()
return actual.beginTx();
}

@Override
public Transaction beginTx( long timeout )
{
return actual.beginTx( timeout );
}

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

@Override
Expand Down
Expand Up @@ -45,8 +45,9 @@
import org.neo4j.kernel.configuration.Config;
import org.neo4j.kernel.configuration.Settings;
import org.neo4j.kernel.guard.GuardTimeoutException;
import org.neo4j.kernel.impl.factory.CommunityFacadeFactory;
import org.neo4j.kernel.impl.factory.CommunityEditionModule;
import org.neo4j.kernel.impl.factory.DataSourceModule;
import org.neo4j.kernel.impl.factory.DatabaseInfo;
import org.neo4j.kernel.impl.factory.EditionModule;
import org.neo4j.kernel.impl.factory.GraphDatabaseFacade;
import org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory;
Expand All @@ -63,9 +64,9 @@
import org.neo4j.shell.impl.CollectingOutput;
import org.neo4j.shell.impl.SameJvmClient;
import org.neo4j.shell.kernel.GraphDatabaseShellServer;
import org.neo4j.test.CleanupRule;
import org.neo4j.test.TestGraphDatabaseFactory;
import org.neo4j.test.TestGraphDatabaseFactoryState;
import org.neo4j.test.rule.CleanupRule;
import org.neo4j.test.server.HTTP;
import org.neo4j.time.FakeClock;

Expand Down Expand Up @@ -227,7 +228,6 @@ private Map<Setting<?>,String> getSettingsMap()
GraphDatabaseSettings.auth_enabled, "false" );
}


private String transactionUri(CommunityNeoServer neoServer)
{
return neoServer.baseUri().toString() + "db/data/transaction";
Expand Down Expand Up @@ -306,9 +306,9 @@ private class GuardTestServer extends CommunityNeoServer
private class GuardTestGraphDatabaseFactory extends TestGraphDatabaseFactory
{

private CommunityFacadeFactory customFacadeFactory;
private GraphDatabaseFacadeFactory customFacadeFactory;

GuardTestGraphDatabaseFactory( CommunityFacadeFactory customFacadeFactory )
GuardTestGraphDatabaseFactory( GraphDatabaseFacadeFactory customFacadeFactory )
{
this.customFacadeFactory = customFacadeFactory;
}
Expand All @@ -322,13 +322,14 @@ protected GraphDatabaseBuilder.DatabaseCreator createImpermanentDatabaseCreator(
}
}

private class GuardCommunityFacadeFactory extends CommunityFacadeFactory
private class GuardCommunityFacadeFactory extends GraphDatabaseFacadeFactory
{

private Clock clock;

GuardCommunityFacadeFactory( Clock clock )
{
super( DatabaseInfo.COMMUNITY, CommunityEditionModule::new);
this.clock = clock;
}

Expand Down

0 comments on commit 67ed213

Please sign in to comment.