/// <inheritdoc /> public void Dispose() { if (!_disposed) { if (_currentTransaction != null) { switch (_currentTransaction.State) { case CoreTransactionState.Starting: case CoreTransactionState.InProgress: try { AbortTransaction(CancellationToken.None); } catch { // ignore exceptions } break; } } _currentTransaction?.UnpinAll(); _serverSession.Dispose(); _disposed = true; } }
/// <inheritdoc /> public void AboutToSendCommand() { if (_currentTransaction != null) { switch (_currentTransaction.State) { case CoreTransactionState.Starting: // Starting changes to InProgress after the message is sent to the server case CoreTransactionState.InProgress: return; case CoreTransactionState.Aborted: _currentTransaction = null; break; case CoreTransactionState.Committed: // don't set to null when retrying a commit if (!_isCommitTransactionInProgress) { // Unpin data non-transaction operation uses the commited session _currentTransaction.UnpinAll(); _currentTransaction = null; } return; default: throw new Exception($"Unexpected transaction state: {_currentTransaction.State}."); } } }
// public methods /// <inheritdoc /> public void AbortTransaction(CancellationToken cancellationToken = default(CancellationToken)) { EnsureAbortTransactionCanBeCalled(nameof(AbortTransaction)); try { if (_currentTransaction.IsEmpty) { return; } try { var firstAttempt = CreateAbortTransactionOperation(); ExecuteEndTransactionOnPrimary(firstAttempt, cancellationToken); return; } catch (Exception exception) when(ShouldRetryEndTransactionException(exception)) { // unpin if retryable error _currentTransaction.UnpinAll(); // ignore exception and retry } catch { return; // ignore exception and return } try { var secondAttempt = CreateAbortTransactionOperation(); ExecuteEndTransactionOnPrimary(secondAttempt, cancellationToken); } catch { return; // ignore exception and return } } finally { _currentTransaction.SetState(CoreTransactionState.Aborted); // The transaction is aborted.The session MUST be unpinned regardless // of whether the abortTransaction command succeeds or fails _currentTransaction.UnpinAll(); } }