Skip to content

Commit

Permalink
Add possibility to access transaction id and transaction commit time …
Browse files Browse the repository at this point in the history
…in afterCommit TransactionEventHandler and in TransactionHook.

Add possibility to access transaction id and transaction commit time from KernelTransaction.
Propagate newly available info into TransactionData.
  • Loading branch information
MishaDemianenko committed Aug 8, 2016
1 parent 039d4bb commit e3dac30
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 11 deletions.
Expand Up @@ -34,6 +34,17 @@
*/
public interface TransactionData
{

/**
* Not committed transaction id.
*/
int UNASSIGNED_TRANSACTION_ID = -1;

/**
* Not committed transaction commit time.
*/
int UNASSIGNED_COMMIT_TIME = -1;

/**
* Get the nodes that were created during the transaction.
*
Expand All @@ -47,7 +58,7 @@ public interface TransactionData
* @return all nodes that were deleted during the transaction.
*/
Iterable<Node> deletedNodes();

/**
* Returns whether or not {@code node} is deleted in this transaction.
* @param node the {@link Node} to check whether or not it is deleted
Expand Down Expand Up @@ -119,7 +130,7 @@ public interface TransactionData
/**
* Returns whether or not {@code relationship} is deleted in this
* transaction.
*
*
* @param relationship the {@link Relationship} to check whether or not it
* is deleted in this transaction.
* @return whether or not {@code relationship} is deleted in this
Expand Down Expand Up @@ -159,4 +170,24 @@ public interface TransactionData
* @return all properties that have been removed from relationships.
*/
Iterable<PropertyEntry<Relationship>> removedRelationshipProperties();

/**
* Return transaction id if it was already assigned or {@link #UNASSIGNED_TRANSACTION_ID} otherwise.
* Transaction id is assigned as soon as transaction committed.
* @return transaction id.
*/
default long getTransactionId()
{
return UNASSIGNED_TRANSACTION_ID;
}

/**
* Return transaction commit time if it was already assigned or {@link #UNASSIGNED_COMMIT_TIME} otherwise.
* Transaction commit time is assigned as soon as transaction committed.
* @return transaction commit time
*/
default long getCommitTime()
{
return UNASSIGNED_COMMIT_TIME;
}
}
Expand Up @@ -19,6 +19,7 @@
*/
package org.neo4j.kernel.api;

import org.neo4j.graphdb.event.TransactionData;
import org.neo4j.kernel.api.exceptions.Status;
import org.neo4j.kernel.api.exceptions.TransactionFailureException;
import org.neo4j.kernel.api.security.AccessMode;
Expand Down Expand Up @@ -169,6 +170,26 @@ interface CloseListener
*/
Type transactionType();

/**
* Return transaction id if it was already assigned or {@link TransactionData#UNASSIGNED_TRANSACTION_ID} otherwise.
* Transaction id is assigned as soon as transaction committed.
* @return transaction id.
*/
default long getTransactionId()
{
return TransactionData.UNASSIGNED_TRANSACTION_ID;
}

/**
* Return transaction commit time if it was already assigned or {@link TransactionData#UNASSIGNED_COMMIT_TIME} otherwise.
* Transaction commit time is assigned as soon as transaction committed.
* @return transaction commit time
*/
default long getCommitTime()
{
return TransactionData.UNASSIGNED_COMMIT_TIME;
}

Revertable restrict( AccessMode mode );

interface Revertable extends AutoCloseable
Expand Down
Expand Up @@ -28,7 +28,7 @@
*/
public interface TransactionHook<OUTCOME extends TransactionHook.Outcome>
{
public interface Outcome
interface Outcome
{
boolean isSuccessful();
Throwable failure();
Expand Down
Expand Up @@ -27,6 +27,7 @@

import org.neo4j.collection.pool.Pool;
import org.neo4j.graphdb.TransactionTerminatedException;
import org.neo4j.graphdb.event.TransactionData;
import org.neo4j.helpers.Clock;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.KeyReadTokenNameLookup;
Expand Down Expand Up @@ -155,6 +156,8 @@ TransactionWriteState upgradeToSchemaWrites() throws InvalidTransactionTypeKerne
private volatile long lastTransactionTimestampWhenStarted;
private TransactionEvent transactionEvent;
private Type type;
private long transactionId;
private long commitTime;
private volatile int reuseCount;

/**
Expand Down Expand Up @@ -216,6 +219,8 @@ public KernelTransactionImplementation initialize(
this.transactionEvent = tracer.beginTransaction();
assert transactionEvent != null : "transactionEvent was null!";
this.accessMode = accessMode;
this.transactionId = TransactionData.UNASSIGNED_TRANSACTION_ID;
this.commitTime = TransactionData.UNASSIGNED_COMMIT_TIME;
this.currentStatement.initialize( statementLocks );
return this;
}
Expand Down Expand Up @@ -556,14 +561,17 @@ private void commit() throws TransactionFailureException
PhysicalTransactionRepresentation transactionRepresentation =
new PhysicalTransactionRepresentation( extractedCommands );
TransactionHeaderInformation headerInformation = headerInformationFactory.create();
long timeCommitted = clock.currentTimeMillis();
transactionRepresentation.setHeader( headerInformation.getAdditionalHeader(),
headerInformation.getMasterId(),
headerInformation.getAuthorId(),
startTimeMillis, lastTransactionIdWhenStarted, clock.currentTimeMillis(),
startTimeMillis, lastTransactionIdWhenStarted, timeCommitted,
commitLocks.getLockSessionId() );

// Commit the transaction
commitProcess.commit( new TransactionToApply( transactionRepresentation ), commitEvent, INTERNAL );
transactionId = commitProcess
.commit( new TransactionToApply( transactionRepresentation ), commitEvent, INTERNAL );
commitTime = timeCommitted;
}
}
success = true;
Expand Down Expand Up @@ -727,6 +735,18 @@ public Type transactionType()
return type;
}

@Override
public long getTransactionId()
{
return transactionId;
}

@Override
public long getCommitTime()
{
return commitTime;
}

@Override
public Revertable restrict( AccessMode mode )
{
Expand Down
Expand Up @@ -33,6 +33,7 @@
import org.neo4j.graphdb.event.PropertyEntry;
import org.neo4j.graphdb.event.TransactionData;
import org.neo4j.helpers.collection.IterableWrapper;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.exceptions.EntityNotFoundException;
import org.neo4j.kernel.api.exceptions.LabelNotFoundKernelException;
import org.neo4j.kernel.api.exceptions.PropertyKeyIdNotFoundKernelException;
Expand Down Expand Up @@ -62,6 +63,7 @@ public class TxStateTransactionDataSnapshot implements TransactionData
private final StorageStatement storeStatement;
private final RelationshipActions relationshipActions;
private final StoreReadLayer store;
private KernelTransaction transaction;

private final Collection<PropertyEntry<Node>> assignedNodeProperties = new ArrayList<>();
private final Collection<PropertyEntry<Relationship>> assignedRelationshipProperties = new ArrayList<>();
Expand All @@ -74,14 +76,15 @@ public class TxStateTransactionDataSnapshot implements TransactionData

public TxStateTransactionDataSnapshot(
ReadableTransactionState state,
NodeProxy.NodeActions nodeActions, RelationshipProxy.RelationshipActions relationshipActions,
StoreReadLayer storeReadLayer, StorageStatement storageStatement )
NodeProxy.NodeActions nodeActions, RelationshipActions relationshipActions,
StoreReadLayer storeReadLayer, StorageStatement storageStatement, KernelTransaction transaction )
{
this.state = state;
this.nodeActions = nodeActions;
this.relationshipActions = relationshipActions;
this.storeStatement = storageStatement;
this.store = storeReadLayer;
this.transaction = transaction;

// Load changes that require store access eagerly, because we won't have access to the after-state
// after the tx has been committed.
Expand Down Expand Up @@ -160,6 +163,18 @@ public Iterable<LabelEntry> assignedLabels()
return assignedLabels;
}

@Override
public long getTransactionId()
{
return transaction.getTransactionId();
}

@Override
public long getCommitTime()
{
return transaction.getCommitTime();
}

private void takeSnapshot()
{
try
Expand Down
Expand Up @@ -115,7 +115,7 @@ public TransactionHandlerState beforeCommit( ReadableTransactionState state, Ker

TransactionData txData = state == null ? EMPTY_DATA :
new TxStateTransactionDataSnapshot( state, nodeActions, relationshipActions,
storeReadLayer, statement );
storeReadLayer, statement, transaction );

TransactionHandlerState handlerStates = new TransactionHandlerState( txData );
for ( TransactionEventHandler<?> handler : this.transactionEventHandlers )
Expand Down
Expand Up @@ -30,6 +30,7 @@
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.event.LabelEntry;
import org.neo4j.graphdb.event.PropertyEntry;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.Statement;
import org.neo4j.kernel.api.properties.DefinedProperty;
import org.neo4j.kernel.api.properties.Property;
Expand All @@ -44,6 +45,7 @@

import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
Expand All @@ -60,6 +62,7 @@ public class TxStateTransactionDataViewTest
private final Statement stmt = mock( Statement.class );
private final StoreReadLayer ops = mock( StoreReadLayer.class );
private final StoreStatement storeStatement = mock( StoreStatement.class );
private final KernelTransaction transaction = mock( KernelTransaction.class );

private final TransactionState state = new TxState();

Expand Down Expand Up @@ -283,6 +286,19 @@ public void shouldListRemovedLabels() throws Exception
assertThat( entry.node().getId(), equalTo( 1l ) );
}

@Test
public void accessTransactionIdAndCommitTime()
{
long committedTransactionId = 7L;
long commitTime = 10L;
when( transaction.getTransactionId() ).thenReturn( committedTransactionId );
when( transaction.getCommitTime() ).thenReturn( commitTime );

TxStateTransactionDataSnapshot transactionDataSnapshot = snapshot();
assertEquals( committedTransactionId, transactionDataSnapshot.getTransactionId() );
assertEquals( commitTime, transactionDataSnapshot.getCommitTime() );
}

private List<Long> idList( Iterable<? extends PropertyContainer> entities )
{
List<Long> out = new ArrayList<>();
Expand All @@ -297,6 +313,6 @@ private TxStateTransactionDataSnapshot snapshot()
{
NodeProxy.NodeActions nodeActions = mock( NodeProxy.NodeActions.class );
final RelationshipProxy.RelationshipActions relActions = mock( RelationshipProxy.RelationshipActions.class );
return new TxStateTransactionDataSnapshot( state, nodeActions, relActions, ops, storeStatement );
return new TxStateTransactionDataSnapshot( state, nodeActions, relActions, ops, storeStatement, transaction );
}
}

0 comments on commit e3dac30

Please sign in to comment.