@Test public void transactionStateShouldReflectRemovingLabelImmediately() throws Exception { // GIVEN Transaction tx = db.beginTx(); Statement statement = statementContextProvider.instance(); Node node = db.createNode(); int labelId1 = statement.dataWriteOperations().labelGetOrCreateForName("labello1"); int labelId2 = statement.dataWriteOperations().labelGetOrCreateForName("labello2"); statement.dataWriteOperations().nodeAddLabel(node.getId(), labelId1); statement.dataWriteOperations().nodeAddLabel(node.getId(), labelId2); statement.close(); tx.success(); tx.finish(); tx = db.beginTx(); statement = statementContextProvider.instance(); // WHEN statement.dataWriteOperations().nodeRemoveLabel(node.getId(), labelId2); // THEN PrimitiveIntIterator labelsIterator = statement.readOperations().nodeGetLabels(node.getId()); Set<Integer> labels = asSet(labelsIterator); assertFalse(statement.readOperations().nodeHasLabel(node.getId(), labelId2)); assertEquals(asSet(labelId1), labels); statement.close(); tx.success(); tx.finish(); }
/** * While we transition ownership from the Beans API to the Kernel API for core database * interactions, there will be a bit of a mess. Our first goal is an architecture like this: * * <p>Users / \ Beans API Cypher \ / Kernel API | Kernel Implementation * * <p>But our current intermediate architecture looks like this: * * <p>Users / \ Beans API <--- Cypher | \ / | Kernel API | | Kernel Implementation * * <p>Meaning Kernel API and Beans API both manipulate the underlying kernel, causing lots of * corner cases. Most notably, those corner cases are related to Transactions, and the interplay * between three transaction APIs: - The Beans API - The JTA Transaction Manager API - The Kernel * TransactionContext API * * <p>In the long term, the goal is for JTA compliant stuff to live outside of the kernel, as an * addon. The Kernel API will rule supreme over the land of transactions. We are a long way away * from there, however, so as a first intermediary step, the JTA transaction manager rules * supreme, and the Kernel API piggybacks on it. * * <p>This test shows us how to use both the Kernel API and the Beans API together in the same * transaction, during the transition phase. */ @Test public void mixingBeansApiWithKernelAPI() throws Exception { // 1: Start your transactions through the Beans API Transaction beansAPITx = db.beginTx(); // 2: Get a hold of a KernelAPI statement context for the *current* transaction this way: Statement statement = statementContextProvider.instance(); // 3: Now you can interact through both the statement context and the kernel API to manipulate // the // same transaction. Node node = db.createNode(); int labelId = statement.dataWriteOperations().labelGetOrCreateForName("labello"); statement.dataWriteOperations().nodeAddLabel(node.getId(), labelId); // 4: Close the StatementContext statement.close(); // 5: Commit through the beans API beansAPITx.success(); beansAPITx.finish(); // NOTE: Transactions are still thread-bound right now, because we use JTA to "own" // transactions, // meaning if you use // both the Kernel API to create transactions while a Beans API transaction is running in the // same // thread, the results are undefined. // When the Kernel API implementation is done, the Kernel API transaction implementation is not // meant // to be bound to threads. }
@Test public void labelShouldBeRemovedAfterCommit() throws Exception { // GIVEN Transaction tx = db.beginTx(); Statement statement = statementContextProvider.instance(); Node node = db.createNode(); int labelId1 = statement.dataWriteOperations().labelGetOrCreateForName("labello1"); statement.dataWriteOperations().nodeAddLabel(node.getId(), labelId1); statement.close(); tx.success(); tx.finish(); // WHEN tx = db.beginTx(); statement = statementContextProvider.instance(); statement.dataWriteOperations().nodeRemoveLabel(node.getId(), labelId1); statement.close(); tx.success(); tx.finish(); // THEN tx = db.beginTx(); statement = statementContextProvider.instance(); PrimitiveIntIterator labels = statement.readOperations().nodeGetLabels(node.getId()); statement.close(); tx.success(); tx.finish(); assertThat(asSet(labels), equalTo(Collections.<Integer>emptySet())); }
@Test public void shouldNotBeAbleToCommitIfFailedTransactionContext() throws Exception { Transaction tx = db.beginTx(); Statement statement = statementContextProvider.instance(); // WHEN Node node = null; int labelId = -1; try { node = db.createNode(); labelId = statement.dataWriteOperations().labelGetOrCreateForName("labello"); statement.dataWriteOperations().nodeAddLabel(node.getId(), labelId); statement.close(); tx.failure(); tx.success(); tx.finish(); fail("Should have failed"); } catch (TransactionFailureException e) { // Expected } // THEN tx = db.beginTx(); statement = statementContextProvider.instance(); try { statement.readOperations().nodeHasLabel(node.getId(), labelId); fail("should have thrown exception"); } catch (EntityNotFoundException e) { // Yay! } tx.finish(); }
@Test public void mixingBeansApiWithKernelAPIForNestedTransaction() throws Exception { // GIVEN Transaction outerTx = db.beginTx(); Statement statement = statementContextProvider.instance(); // WHEN Node node = db.createNode(); int labelId = statement.dataWriteOperations().labelGetOrCreateForName("labello"); statement.dataWriteOperations().nodeAddLabel(node.getId(), labelId); statement.close(); outerTx.finish(); }
private long createNode( Statement statement, String labelName, String propertyKeyName, Object value) throws KernelException { int labelId = statement.tokenWriteOperations().labelGetOrCreateForName(labelName); int propertyKeyId = statement.tokenWriteOperations().propertyKeyGetOrCreateForName(propertyKeyName); long nodeId = statement.dataWriteOperations().nodeCreate(); statement.dataWriteOperations().nodeAddLabel(nodeId, labelId); statement .dataWriteOperations() .nodeSetProperty(nodeId, Property.property(propertyKeyId, value)); return nodeId; }
@Test public void deletingNodeWithLabelsShouldHaveThoseLabelRemovalsReflectedInTransaction() throws Exception { // GIVEN Transaction tx = db.beginTx(); Label label = label("labello"); Node node = db.createNode(label); tx.success(); tx.finish(); tx = db.beginTx(); Statement statement = statementContextProvider.instance(); // WHEN statement.dataWriteOperations().nodeDelete(node.getId()); // Then int labelId = statement.readOperations().labelGetForName(label.name()); Set<Integer> labels = asSet(statement.readOperations().nodeGetLabels(node.getId())); boolean labelIsSet = statement.readOperations().nodeHasLabel(node.getId(), labelId); Set<Long> nodes = asSet(statement.readOperations().nodesGetForLabel(labelId)); statement.close(); tx.success(); tx.finish(); assertEquals(emptySetOf(Long.class), nodes); assertEquals(emptySetOf(Integer.class), labels); assertFalse("Label should not be set on node here", labelIsSet); }
private void deleteNode(long nodeId) throws KernelException { try (Transaction tx = db.beginTx()) { Statement statement = bridge.instance(); statement.dataWriteOperations().nodeDelete(nodeId); tx.success(); } }
@Test public void removingNonExistentLabelFromNodeShouldRespondFalse() throws Exception { // GIVEN Transaction tx = db.beginTx(); Node node = db.createNode(); Statement statement = statementContextProvider.instance(); int labelId = statement.dataWriteOperations().labelGetOrCreateForName("mylabel"); statement.close(); tx.success(); tx.finish(); // WHEN tx = db.beginTx(); statement = statementContextProvider.instance(); boolean removed = statement.dataWriteOperations().nodeRemoveLabel(node.getId(), labelId); // THEN assertFalse("Shouldn't have been removed now", removed); tx.finish(); }
@Test public void addingExistingLabelToNodeShouldRespondFalse() throws Exception { // GIVEN Transaction tx = db.beginTx(); Node node = db.createNode(); Statement statement = statementContextProvider.instance(); int labelId = statement.dataWriteOperations().labelGetOrCreateForName("mylabel"); statement.close(); tx.success(); tx.finish(); // WHEN tx = db.beginTx(); statement = statementContextProvider.instance(); boolean added = statement.dataWriteOperations().nodeAddLabel(node.getId(), labelId); // THEN assertTrue("Should have been added now", added); tx.finish(); }
private void changeName(long nodeId, String propertyKeyName, Object newValue) throws KernelException { try (Transaction tx = db.beginTx()) { Statement statement = bridge.instance(); int propertyKeyId = statement.tokenWriteOperations().propertyKeyGetOrCreateForName(propertyKeyName); statement .dataWriteOperations() .nodeSetProperty(nodeId, Property.property(propertyKeyId, newValue)); tx.success(); } }
@Test public void transactionStateShouldRemovePreviouslyAddedLabel() throws Exception { Transaction tx = db.beginTx(); Statement statement = statementContextProvider.instance(); // WHEN Node node = db.createNode(); int labelId1 = statement.dataWriteOperations().labelGetOrCreateForName("labello1"); int labelId2 = statement.dataWriteOperations().labelGetOrCreateForName("labello2"); statement.dataWriteOperations().nodeAddLabel(node.getId(), labelId1); statement.dataWriteOperations().nodeAddLabel(node.getId(), labelId2); statement.dataWriteOperations().nodeRemoveLabel(node.getId(), labelId2); statement.close(); tx.success(); tx.finish(); // THEN tx = db.beginTx(); statement = statementContextProvider.instance(); assertEquals(asSet(labelId1), asSet(statement.readOperations().nodeGetLabels(node.getId()))); tx.finish(); }
@Test public void changesInTransactionContextShouldBeRolledBackWhenTxIsRolledBack() throws Exception { // GIVEN Transaction tx = db.beginTx(); Statement statement = statementContextProvider.instance(); // WHEN Node node = db.createNode(); int labelId = statement.dataWriteOperations().labelGetOrCreateForName("labello"); statement.dataWriteOperations().nodeAddLabel(node.getId(), labelId); statement.close(); tx.finish(); // THEN tx = db.beginTx(); statement = statementContextProvider.instance(); try { statement.readOperations().nodeHasLabel(node.getId(), labelId); fail("should have thrown exception"); } catch (EntityNotFoundException e) { // Yay! } tx.finish(); }