use of org.neo4j.kernel.api.KernelTransaction in project neo4j by neo4j.
the class Neo4jTransactionalContext method commitAndRestartTx.
@Override
public void commitAndRestartTx() {
/*
* This method is use by the Cypher runtime to cater for PERIODIC COMMIT, which allows a single query to
* periodically, after x number of rows, to commit a transaction and spawn a new one.
*
* To still keep track of the running stream after switching transactions, we need to open the new transaction
* before closing the old one. This way, a query will not disappear and appear when switching transactions.
*
* Since our transactions are thread bound, we must first unbind the old transaction from the thread before
* creating a new one. And then we need to do that thread switching again to close the old transaction.
*/
// (1) Unbind current transaction
QueryRegistryOperations oldQueryRegistryOperations = statement.queryRegistration();
InternalTransaction oldTransaction = transaction;
KernelTransaction oldKernelTx = txBridge.getKernelTransactionBoundToThisThread(true);
txBridge.unbindTransactionFromCurrentThread();
// (2) Create, bind, register, and unbind new transaction
transaction = graph.beginTransaction(transactionType, securityContext);
statement = txBridge.get();
statement.queryRegistration().registerExecutingQuery(executingQuery);
KernelTransaction kernelTx = txBridge.getKernelTransactionBoundToThisThread(true);
txBridge.unbindTransactionFromCurrentThread();
// (3) Rebind old transaction just to commit and close it (and unregister as a side effect of that)
txBridge.bindTransactionToCurrentThread(oldKernelTx);
oldQueryRegistryOperations.unregisterExecutingQuery(executingQuery);
try {
oldTransaction.success();
oldTransaction.close();
} catch (Throwable t) {
// Corner case: The old transaction might have been terminated by the user. Now we also need to
// terminate the new transaction.
txBridge.bindTransactionToCurrentThread(kernelTx);
transaction.failure();
transaction.close();
txBridge.unbindTransactionFromCurrentThread();
throw t;
}
// (4) Unbind the now closed old transaction and rebind the new transaction for continued execution
txBridge.unbindTransactionFromCurrentThread();
txBridge.bindTransactionToCurrentThread(kernelTx);
}
use of org.neo4j.kernel.api.KernelTransaction in project neo4j by neo4j.
the class TransactionBatchCommitterTest method newKernelTransaction.
private KernelTransaction newKernelTransaction(long lastTransactionTimestampWhenStarted) {
KernelTransaction txToTerminate = mock(KernelTransaction.class);
when(txToTerminate.lastTransactionTimestampWhenStarted()).thenReturn(lastTransactionTimestampWhenStarted);
return txToTerminate;
}
use of org.neo4j.kernel.api.KernelTransaction in project neo4j by neo4j.
the class StoreMigratorFrom21IT method mustMendDuplicatePropertiesWhenUpgradingFromVersion21.
@Test
public void mustMendDuplicatePropertiesWhenUpgradingFromVersion21() throws Exception {
// The rules:
// If an index is present, all duplicates should be removed and the property set to the value in the index
// If an index is not present, the property should be set to the value of the last duplicate in the property
// chain, all duplicates except the first should be removed
// If an index is not present, the first property in the duplicate chain should be kept for the users
// benefit, moved to a special property value, `__DUPLICATE_<propkey>`
//
// This is the broken store that we are upgrading:
//
// (#0:Label { keyA: "actual", keyA: "phony!", keyA: "phony!" })
// (#1 { keyA: "actual", keyA: "actual", keyA: "actual" })
// (#2:Label { keyA: "real1", keyA: "phony", keyA: "phony", keyD: "real2", keyD: "phony", keyD: "phony" })
// (#3 { keyA: "real1", keyA: "phony", keyA: "phony", keyD: "real2", keyD: "phony", keyD: "phony" })
// (#4 { keyA: "actual", keyB: "actual", keyC: "actual" })
// (#0)-[#0:REL { keyA: "actual", keyA: "actual", keyA: "actual" }]->(#1)
// (#0)-[#1:REL { keyA: "real1", keyA: "phony", keyA: "phony",
// keyD: "real2", keyE: "phony", keyF: "phony" }]->(#1)
// (#2)-[#2:REL { keyA: "actual", keyB: "actual", keyC: "actual" }]->(#0)
//
// And this is what we want to end up with, after upgrading:
//
// (#0:Label { keyA: "actual" })
// (#1 { keyA: "actual", __DUPLICATE_keyA: "actual" })
// (#2:Label { keyA: "real1", keyD: "real2" })
// (#3 { keyA: "real1", __DUPLICATE_keyA_1: "real1", __DUPLICATE_keyA_2: "real1",
// keyD: "real2", __DUPLICATE_keyD_1: "real2", __DUPLICATE_keyD_2: "real2" })
// (#4 { keyA: "actual", keyB: "actual", keyC: "actual" })
// (#0)-[#0:REL { keyA: "actual", __DUPLICATE_keyA: "actual" }]->(#1)
// (#0)-[#1:REL { keyA: "real1", __DUPLICATE_keyA_1: "real1", __DUPLICATE_keyA_2: "real1",
// keyD: "real2", __DUPLICATE_keyD_1: "real2", __DUPLICATE_keyD_2: "real2" }]->(#1)
// (#2)-[#2:REL { keyA: "actual", keyB: "actual", keyC: "actual" }]->(#0)
File dir = MigrationTestUtils.find21FormatStoreDirectoryWithDuplicateProperties(storeDir.directory());
TestGraphDatabaseFactory factory = new TestGraphDatabaseFactory();
GraphDatabaseBuilder builder = factory.newEmbeddedDatabaseBuilder(dir).setConfig(GraphDatabaseSettings.allow_store_upgrade, "true");
GraphDatabaseService database = builder.newGraphDatabase();
database.shutdown();
ConsistencyCheckService service = new ConsistencyCheckService();
ConsistencyCheckService.Result result = service.runFullConsistencyCheck(dir.getAbsoluteFile(), Config.empty(), ProgressMonitorFactory.NONE, NullLogProvider.getInstance(), false);
assertTrue(result.isSuccessful());
database = builder.newGraphDatabase();
// Upgrade is now completed. Verify the contents:
DependencyResolver dependencyResolver = ((GraphDatabaseAPI) database).getDependencyResolver();
// Verify that the properties appear correct to the outside world:
try (Transaction ignore = database.beginTx()) {
verifyProperties(database.getNodeById(0), Pair.of("keyA", new Object[] { "actual", "phony!", "phony!" }));
verifyProperties(database.getNodeById(1), Pair.of("keyA", new Object[] { "actual", "actual", "actual" }));
verifyProperties(database.getNodeById(2), Pair.of("keyA", new Object[] { "real1", "phony", "phony" }), Pair.of("keyD", new Object[] { "real2", "phony", "phony" }));
verifyProperties(database.getNodeById(3), Pair.of("keyA", new Object[] { "real1", "real1", "real1" }), Pair.of("keyD", new Object[] { "real2", "real2", "real2" }));
verifyProperties(database.getNodeById(4), Pair.of("keyA", new Object[] { "actual" }), Pair.of("keyB", new Object[] { "actual" }), Pair.of("keyC", new Object[] { "actual" }));
verifyProperties(database.getRelationshipById(0), Pair.of("keyA", new Object[] { "actual", "actual", "actual" }));
verifyProperties(database.getRelationshipById(1), Pair.of("keyA", new Object[] { "real1", "real1", "real1" }), Pair.of("keyD", new Object[] { "real2", "real2", "real2" }));
verifyProperties(database.getRelationshipById(2), Pair.of("keyA", new Object[] { "actual" }), Pair.of("keyB", new Object[] { "actual" }), Pair.of("keyC", new Object[] { "actual" }));
}
// Verify that there are no two properties on the entities, that have the same key:
// (This is important because the verification above cannot tell if we have two keys with the same value)
KernelAPI kernel = dependencyResolver.resolveDependency(KernelAPI.class);
try (KernelTransaction tx = kernel.newTransaction(KernelTransaction.Type.implicit, AnonymousContext.read());
Statement statement = tx.acquireStatement()) {
Iterators.asUniqueSet(statement.readOperations().nodeGetPropertyKeys(0));
Iterators.asUniqueSet(statement.readOperations().nodeGetPropertyKeys(1));
Iterators.asUniqueSet(statement.readOperations().nodeGetPropertyKeys(2));
Iterators.asUniqueSet(statement.readOperations().relationshipGetPropertyKeys(0));
Iterators.asUniqueSet(statement.readOperations().relationshipGetPropertyKeys(1));
}
database.shutdown();
}
use of org.neo4j.kernel.api.KernelTransaction in project neo4j by neo4j.
the class TestMigrateToDenseNodeSupport method verifyDenseRepresentation.
private void verifyDenseRepresentation(GraphDatabaseService db, Node node, boolean dense) {
KernelAPI kernelAPI = ((GraphDatabaseAPI) db).getDependencyResolver().resolveDependency(KernelAPI.class);
try (KernelTransaction tx = kernelAPI.newTransaction(KernelTransaction.Type.implicit, AnonymousContext.read());
Statement statement = tx.acquireStatement()) {
Cursor<NodeItem> nodeCursor = statement.readOperations().nodeCursorById(node.getId());
assertEquals(dense, nodeCursor.get().isDense());
} catch (TransactionFailureException | IllegalArgumentException | EntityNotFoundException e) {
throw new RuntimeException(e);
}
}
use of org.neo4j.kernel.api.KernelTransaction in project neo4j by neo4j.
the class TransactionStateChecker method create.
public static TransactionStateChecker create(TransitionalPeriodTransactionMessContainer container) {
KernelTransaction topLevelTransactionBoundToThisThread = container.getBridge().getTopLevelTransactionBoundToThisThread(true);
KernelStatement kernelStatement = (KernelStatement) topLevelTransactionBoundToThisThread.acquireStatement();
return new TransactionStateChecker(nodeId -> kernelStatement.hasTxStateWithChanges() && kernelStatement.txState().nodeIsDeletedInThisTx(nodeId), relId -> kernelStatement.hasTxStateWithChanges() && kernelStatement.txState().relationshipIsDeletedInThisTx(relId));
}
Aggregations