@Test @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES) @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_TRANSACTIONS) @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_THREADED_TRANSACTIONS) public void shouldSupportMultipleThreadsOnTheSameTransaction() throws Exception { final int numberOfThreads = 10; final CountDownLatch latch = new CountDownLatch(numberOfThreads); final Graph threadedG = g.tx().createThreadedTx(); for (int ix = 0; ix < numberOfThreads; ix++) { new Thread(() -> { threadedG.addVertex(); latch.countDown(); }).start(); } latch.await(10000, TimeUnit.MILLISECONDS); // threaded transaction is not yet committed so g should not reflect any change assertVertexEdgeCounts(graph, 0, 0); threadedG.tx().commit(); // there should be one vertex for each thread assertVertexEdgeCounts(graph, numberOfThreads, 0); }
@Test @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = FEATURE_TRANSACTIONS) @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = FEATURE_THREADED_TRANSACTIONS, supported = false) public void shouldThrowOnThreadedTransactionNotSupported() { try { graph.tx().createThreadedTx(); fail("An exception should be thrown since the threaded transaction feature is not supported"); } catch (Exception e) { validateException(Transaction.Exceptions.threadedTransactionsNotSupported(), e); } } }
@Test @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES) @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_TRANSACTIONS) @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_THREADED_TRANSACTIONS) public void shouldOpenTxWhenThreadedTransactionIsCreated() throws Exception { // threaded transactions should be immediately open on creation final Graph threadedG = g.tx().createThreadedTx(); assertThat(threadedG.tx().isOpen(), is(true)); threadedG.tx().rollback(); assertThat(threadedG.tx().isOpen(), is(false)); }
@Test @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES) @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_TRANSACTIONS) @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_THREADED_TRANSACTIONS) public void shouldNotReuseThreadedTransaction() throws Exception { final int numberOfThreads = 10; final CountDownLatch latch = new CountDownLatch(numberOfThreads); final Graph threadedG = g.tx().createThreadedTx(); for (int ix = 0; ix < numberOfThreads; ix++) { new Thread(() -> { threadedG.addVertex(); latch.countDown(); }).start(); } latch.await(10000, TimeUnit.MILLISECONDS); // threaded transaction is not yet committed so g should not reflect any change assertVertexEdgeCounts(graph, 0, 0); threadedG.tx().commit(); // there should be one vertex for each thread assertVertexEdgeCounts(graph, numberOfThreads, 0); try { assertThat(threadedG.tx().isOpen(), is(false)); threadedG.addVertex(); fail("Shouldn't be able to re-use a threaded transaction"); } catch (Exception ex) { assertThat(ex, instanceOf(IllegalStateException.class)); } finally { if (threadedG.tx().isOpen()) threadedG.tx().rollback(); } }
@Test @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES) @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_TRANSACTIONS) @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_THREADED_TRANSACTIONS) public void shouldSupportMultipleThreadsOnTheSameTransaction() throws Exception { final int numberOfThreads = 10; final CountDownLatch latch = new CountDownLatch(numberOfThreads); final Graph threadedG = g.tx().createThreadedTx(); for (int ix = 0; ix < numberOfThreads; ix++) { new Thread(() -> { threadedG.addVertex(); latch.countDown(); }).start(); } latch.await(10000, TimeUnit.MILLISECONDS); // threaded transaction is not yet committed so g should not reflect any change assertVertexEdgeCounts(graph, 0, 0); threadedG.tx().commit(); // there should be one vertex for each thread assertVertexEdgeCounts(graph, numberOfThreads, 0); }
@Override public WrappedFramedGraph<? extends Graph> createThreadedTx() { return new DelegatingFramedGraph<>(this.getDelegate().createThreadedTx(), this.getGraph().getBuilder(), this.getGraph().getTypeResolver()); }
@Override public WrappedFramedGraph<? extends Graph> createThreadedTx() { return new DelegatingFramedGraph<>(this.getDelegate().createThreadedTx(), this.getGraph().getBuilder(), this.getGraph().getTypeResolver()); }
@Test @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = FEATURE_TRANSACTIONS) @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = FEATURE_THREADED_TRANSACTIONS, supported = false) public void shouldThrowOnThreadedTransactionNotSupported() { try { graph.tx().createThreadedTx(); fail("An exception should be thrown since the threaded transaction feature is not supported"); } catch (Exception e) { validateException(Transaction.Exceptions.threadedTransactionsNotSupported(), e); } } }
@Test @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES) @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_TRANSACTIONS) @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_THREADED_TRANSACTIONS) public void shouldOpenTxWhenThreadedTransactionIsCreated() throws Exception { // threaded transactions should be immediately open on creation final Graph threadedG = g.tx().createThreadedTx(); assertThat(threadedG.tx().isOpen(), is(true)); threadedG.tx().rollback(); assertThat(threadedG.tx().isOpen(), is(false)); }
@Test @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES) @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_TRANSACTIONS) @FeatureRequirement(featureClass = Graph.Features.GraphFeatures.class, feature = Graph.Features.GraphFeatures.FEATURE_THREADED_TRANSACTIONS) public void shouldNotReuseThreadedTransaction() throws Exception { final int numberOfThreads = 10; final CountDownLatch latch = new CountDownLatch(numberOfThreads); final Graph threadedG = g.tx().createThreadedTx(); for (int ix = 0; ix < numberOfThreads; ix++) { new Thread(() -> { threadedG.addVertex(); latch.countDown(); }).start(); } latch.await(10000, TimeUnit.MILLISECONDS); // threaded transaction is not yet committed so g should not reflect any change assertVertexEdgeCounts(graph, 0, 0); threadedG.tx().commit(); // there should be one vertex for each thread assertVertexEdgeCounts(graph, numberOfThreads, 0); try { assertThat(threadedG.tx().isOpen(), is(false)); threadedG.addVertex(); fail("Shouldn't be able to re-use a threaded transaction"); } catch (Exception ex) { assertThat(ex, instanceOf(IllegalStateException.class)); } finally { if (threadedG.tx().isOpen()) threadedG.tx().rollback(); } }