public override 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. */ CheckNotTerminated(); CollectTransactionExecutionStatistic(); // (1) Unbind current transaction QueryRegistryOperations oldQueryRegistryOperations = _statement.queryRegistration(); Statement oldStatement = _statement; InternalTransaction oldTransaction = _transaction; KernelTransaction oldKernelTx = _txBridge.getKernelTransactionBoundToThisThread(true); _txBridge.unbindTransactionFromCurrentThread(); // (2) Create, bind, register, and unbind new transaction _transaction = _graph.beginTransaction(TransactionType, SecurityContextConflict); _kernelTransaction = _txBridge.getKernelTransactionBoundToThisThread(true); _statement = _kernelTransaction.acquireStatement(); _statement.queryRegistration().registerExecutingQuery(_executingQuery); _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 { oldStatement.Close(); oldTransaction.Success(); oldTransaction.Close(); } catch (Exception t) { // Corner case: The old transaction might have been terminated by the user. Now we also need to // terminate the new transaction. _txBridge.bindTransactionToCurrentThread(_kernelTransaction); _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(_kernelTransaction); }
private void SetUpMocks() { _queryService = mock(typeof(GraphDatabaseQueryService)); DependencyResolver resolver = mock(typeof(DependencyResolver)); _txBridge = mock(typeof(ThreadToStatementContextBridge)); _initialStatement = mock(typeof(KernelStatement)); _statistics = new ConfiguredExecutionStatistics(this); QueryRegistryOperations queryRegistryOperations = mock(typeof(QueryRegistryOperations)); InternalTransaction internalTransaction = mock(typeof(InternalTransaction)); when(internalTransaction.TerminationReason()).thenReturn(null); when(_initialStatement.queryRegistration()).thenReturn(queryRegistryOperations); when(_queryService.DependencyResolver).thenReturn(resolver); when(resolver.ResolveDependency(typeof(ThreadToStatementContextBridge))).thenReturn(_txBridge); when(_queryService.beginTransaction(any(), any())).thenReturn(internalTransaction); KernelTransaction mockTransaction = mockTransaction(_initialStatement); when(_txBridge.get()).thenReturn(_initialStatement); when(_txBridge.getKernelTransactionBoundToThisThread(true)).thenReturn(mockTransaction); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("ConstantConditions") @Test public void rollsBackNewlyCreatedTransactionIfTerminationDetectedOnCloseDuringPeriodicCommit() public virtual void RollsBackNewlyCreatedTransactionIfTerminationDetectedOnCloseDuringPeriodicCommit() { // Given InternalTransaction initialTransaction = mock(typeof(InternalTransaction), new ReturnsDeepStubs()); KernelTransaction.Type transactionType = KernelTransaction.Type.@implicit; SecurityContext securityContext = SecurityContext.AUTH_DISABLED; when(initialTransaction.TransactionType()).thenReturn(transactionType); when(initialTransaction.SecurityContext()).thenReturn(securityContext); when(initialTransaction.TerminationReason()).thenReturn(null); GraphDatabaseQueryService queryService = mock(typeof(GraphDatabaseQueryService)); Statement initialStatement = mock(typeof(Statement)); KernelTransaction initialKTX = MockTransaction(initialStatement); QueryRegistryOperations initialQueryRegistry = mock(typeof(QueryRegistryOperations)); ExecutingQuery executingQuery = mock(typeof(ExecutingQuery)); PropertyContainerLocker locker = new PropertyContainerLocker(); ThreadToStatementContextBridge txBridge = mock(typeof(ThreadToStatementContextBridge)); Statement secondStatement = mock(typeof(Statement)); KernelTransaction secondKTX = MockTransaction(secondStatement); InternalTransaction secondTransaction = mock(typeof(InternalTransaction)); when(secondTransaction.TerminationReason()).thenReturn(null); QueryRegistryOperations secondQueryRegistry = mock(typeof(QueryRegistryOperations)); when(executingQuery.QueryText()).thenReturn("X"); when(executingQuery.QueryParameters()).thenReturn(EMPTY_MAP); Mockito.doThrow(typeof(Exception)).when(initialTransaction).close(); when(initialStatement.QueryRegistration()).thenReturn(initialQueryRegistry); when(queryService.BeginTransaction(transactionType, securityContext)).thenReturn(secondTransaction); when(txBridge.GetKernelTransactionBoundToThisThread(true)).thenReturn(initialKTX, initialKTX, secondKTX); when(txBridge.Get()).thenReturn(secondStatement); when(secondStatement.QueryRegistration()).thenReturn(secondQueryRegistry); Kernel kernel = mock(typeof(Kernel)); Neo4jTransactionalContext context = new Neo4jTransactionalContext(queryService, txBridge, locker, initialTransaction, initialStatement, executingQuery, kernel); // When try { context.CommitAndRestartTx(); throw new AssertionError("Expected RuntimeException to be thrown"); } catch (Exception) { // Then object[] mocks = new object[] { txBridge, initialTransaction, initialQueryRegistry, initialKTX, secondQueryRegistry, secondKTX, secondTransaction }; InOrder order = Mockito.inOrder(mocks); // (0) Constructor order.verify(initialTransaction).transactionType(); order.verify(initialTransaction).securityContext(); order.verify(txBridge).getKernelTransactionBoundToThisThread(true); order.verify(initialTransaction).terminationReason(); // not terminated check // (1) Collect statistics order.verify(initialKTX).executionStatistics(); // (2) Unbind old order.verify(txBridge).getKernelTransactionBoundToThisThread(true); order.verify(txBridge).unbindTransactionFromCurrentThread(); // (3) Register and unbind new order.verify(txBridge).getKernelTransactionBoundToThisThread(true); order.verify(secondKTX).acquireStatement(); order.verify(secondQueryRegistry).registerExecutingQuery(executingQuery); order.verify(txBridge).unbindTransactionFromCurrentThread(); // (4) Rebind, unregister, and close old order.verify(txBridge).bindTransactionToCurrentThread(initialKTX); order.verify(initialQueryRegistry).unregisterExecutingQuery(executingQuery); order.verify(initialTransaction).success(); order.verify(initialTransaction).close(); order.verify(txBridge).bindTransactionToCurrentThread(secondKTX); order.verify(secondTransaction).failure(); order.verify(secondTransaction).close(); order.verify(txBridge).unbindTransactionFromCurrentThread(); verifyNoMoreInteractions(mocks); } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("ConstantConditions") @Test public void neverStopsExecutingQueryDuringCommitAndRestartTx() public virtual void NeverStopsExecutingQueryDuringCommitAndRestartTx() { // Given KernelTransaction initialKTX = MockTransaction(_initialStatement); InternalTransaction initialTransaction = mock(typeof(InternalTransaction), new ReturnsDeepStubs()); KernelTransaction.Type transactionType = KernelTransaction.Type.@implicit; SecurityContext securityContext = SecurityContext.AUTH_DISABLED; when(initialTransaction.TransactionType()).thenReturn(transactionType); when(initialTransaction.SecurityContext()).thenReturn(securityContext); when(initialTransaction.TerminationReason()).thenReturn(null); QueryRegistryOperations initialQueryRegistry = mock(typeof(QueryRegistryOperations)); ExecutingQuery executingQuery = mock(typeof(ExecutingQuery)); PropertyContainerLocker locker = null; ThreadToStatementContextBridge txBridge = mock(typeof(ThreadToStatementContextBridge)); Statement secondStatement = mock(typeof(Statement)); KernelTransaction secondKTX = MockTransaction(secondStatement); InternalTransaction secondTransaction = mock(typeof(InternalTransaction)); when(secondTransaction.TerminationReason()).thenReturn(null); QueryRegistryOperations secondQueryRegistry = mock(typeof(QueryRegistryOperations)); when(executingQuery.QueryText()).thenReturn("X"); when(executingQuery.QueryParameters()).thenReturn(EMPTY_MAP); when(_initialStatement.queryRegistration()).thenReturn(initialQueryRegistry); when(_queryService.beginTransaction(transactionType, securityContext)).thenReturn(secondTransaction); when(txBridge.GetKernelTransactionBoundToThisThread(true)).thenReturn(initialKTX, initialKTX, secondKTX); when(secondStatement.QueryRegistration()).thenReturn(secondQueryRegistry); Kernel kernel = mock(typeof(Kernel)); Neo4jTransactionalContext context = new Neo4jTransactionalContext(_queryService, txBridge, locker, initialTransaction, _initialStatement, executingQuery, kernel); // When context.CommitAndRestartTx(); // Then object[] mocks = new object[] { txBridge, initialTransaction, initialKTX, initialQueryRegistry, secondQueryRegistry, secondKTX }; InOrder order = Mockito.inOrder(mocks); // (0) Constructor order.verify(initialTransaction).transactionType(); order.verify(initialTransaction).securityContext(); order.verify(txBridge).getKernelTransactionBoundToThisThread(true); order.verify(initialTransaction).terminationReason(); // not terminated check // (1) Collect stats order.verify(initialKTX).executionStatistics(); // (2) Unbind old order.verify(txBridge).getKernelTransactionBoundToThisThread(true); order.verify(txBridge).unbindTransactionFromCurrentThread(); // (3) Register and unbind new order.verify(txBridge).getKernelTransactionBoundToThisThread(true); order.verify(secondKTX).acquireStatement(); order.verify(secondQueryRegistry).registerExecutingQuery(executingQuery); order.verify(txBridge).unbindTransactionFromCurrentThread(); // (4) Rebind, unregister, and close old order.verify(txBridge).bindTransactionToCurrentThread(initialKTX); order.verify(initialQueryRegistry).unregisterExecutingQuery(executingQuery); order.verify(initialTransaction).success(); order.verify(initialTransaction).close(); order.verify(txBridge).unbindTransactionFromCurrentThread(); // (5) Rebind new order.verify(txBridge).bindTransactionToCurrentThread(secondKTX); verifyNoMoreInteractions(mocks); }