/// <summary> /// Dispose the scope. /// </summary> /// <remarks> /// Will dispose transaction unless asked not to do so when being created. During disposal will commit transation /// if it is not owned by managed transaction and marked completed. /// Will restore context if it was changed by the scope, regardless of transaction disposing scenario. /// When restoring context a disposed [previous] transaction (with invalid handle) will be replaced by null. /// </remarks> public void Dispose() { if (!_disposed) { _disposed = true; if (ToBeDisposed) { if (!_current.IsSlave) { if (_completed) { _current.Commit(); } // rollback does not seem necessary - will be done automatically when handle is closed } _current.Dispose(); } if (HasChangedContext) { if (_previous != null && !_previous.IsHandleValid) { _previous = null; } KtmTransaction.Current = _previous; HasChangedContext = false; } } }
/// <summary> /// Create and begin new local KTM transaction (no DTC) /// </summary> /// <returns> /// New <see cref="KtmTransaction" /> instance representing newly started transaction. /// </returns> public static KtmTransaction BeginLocal() { _log.Debug("Starting local standalone KTM transaction"); KtmTransaction retval = new KtmTransaction(KtmTransactionHandle.CreateLocalTransaction(), null); Check.DoEnsure(retval.IsHandleValid, "KtmTransaction failed to initialise"); return(retval); }
/// <summary> /// Detach the underlying transaction from the context. This will ensure that the transaction will not be disposed /// but context handling will not change. /// </summary> /// <returns> /// <see cref="UnderlyingTransaction"/> /// </returns> /// <remarks> /// After detaching <see cref="UnderlyingTransaction"/> will return <see langword="null"/>. /// </remarks> /// <exception cref="InvalidOperationException"> /// <see cref="UnderlyingTransaction"/> is <see langword="null"/> /// </exception> public IFileSystemTransaction DetachTransaction() { Check.DoCheckOperationValid(_current != null, "No transaction to detach"); ToBeDisposed = false; IFileSystemTransaction retval = _current; _current = null; return(retval); }
/// <summary> /// /// </summary> /// <param name="transaction"> /// Transaction to install into the context. If it is equal to the current context KTM transaction the scope will not /// change or restore context at all. /// </param> /// <param name="dispose"> /// Whether to dispose the <paramref name="transaction"/> when disposing scope; disposing will result in commit or rollback /// unless transaction is owned by a managed transaction <see cref="KtmTransaction.IsSlave"/>. /// </param> protected void Initialize(KtmTransaction transaction, bool dispose) { Check.DoCheckArgument(transaction == null || transaction.IsActive, "Transaction must be active"); _completed = false; _previous = KtmTransaction.Current; _current = transaction; ToBeDisposed = transaction != null && dispose; HasChangedContext = transaction != KtmTransaction.Current; if (HasChangedContext) { KtmTransaction.Current = transaction; } }
/// <summary> /// Create scope using the specified KTM transaction. /// </summary> /// <param name="dispose"> /// Whether to dispose transaction created by the scope at the end of the scope. /// </param> /// <returns> /// <see cref="KtmTransactionScope"/> /// </returns> /// <remarks> /// The scope will create new <see cref="KtmTransaction"/> as part of the ambient managed transaction <see cref="Transaction.Current"/> /// and install it as ambient, thread context transaction. At the end of the scope /// (when scope is disposed) the transaction will be disposed according to <paramref name="dispose"/> and thread context will be /// restored. The created KTM transaction will not be committed or rolled back, <see cref="Complete()"/> will have no effect. /// When restoring context a disposed [previous] transaction (with invalid handle) will be replaced by <see langword="null"/>. /// </remarks> public static KtmTransactionScope CreateJoinAmbientManaged(bool dispose) { return(Create(KtmTransaction.GetAmbient(), dispose)); }
/// <summary> /// Create scope with transaction managed (owned) by the specified managed transaction. /// </summary> /// <param name="transaction"> /// Managed transaction to join. /// </param> /// <param name="dispose"> /// Whether to dispose the KTM transaction created by the scope when disposing the scope; disposing will not result in commit /// or rollback. /// </param> /// <returns> /// <see cref="KtmTransactionScope"/> /// </returns> /// The scope will create new <see cref="KtmTransaction"/> and install it as ambient, thread context transaction. At the end of the scope /// (when scope is disposed) the transaction will be disposed according to <paramref name="dispose"/> and the thread context will be restored. /// The created KTM transaction will not be committed or rolled back, <see cref="Complete()"/> will have no effect. /// When restoring context a disposed [previous] transaction (with invalid handle) will be replaced by <see langword="null"/>. public static KtmTransactionScope Create(Transaction transaction, bool dispose) { return(Create(KtmTransaction.Get(transaction), dispose)); }
/// <summary> /// Wrap an existing KTM transaction. /// </summary> /// <param name="transaction"> /// Existing KTM transaction; must be active or <see langword="null"/>. /// </param> /// <param name="dispose"> /// Whether to dispose the <paramref name="transaction"/> when disposing scope; disposing will result in commit or rollback /// unless transaction is owned by a managed transaction <see cref="KtmTransaction.IsSlave"/>. /// </param> protected KtmTransactionScope(KtmTransaction transaction, bool dispose) { Initialize(transaction, dispose); }
/// <summary> /// Create standalone KTM transaction scope not joining ambient managed transaction (if present). /// </summary> /// <param name="dispose"> /// Whether to dispose transaction created by the scope at the end of the scope. /// </param> /// <returns> /// <see cref="KtmTransactionScope"/> /// </returns> /// <remarks> /// The scope will create new <see cref="KtmTransaction"/> and install it as ambient, thread context transaction. At the end of the scope /// (when scope is disposed) the transaction will be disposed according to <paramref name="dispose"/> and the thread context will be restored. /// Before disposing the transaction it will be committed if the scope has been marked as completed (<see cref="Complete()"/>). /// When restoring context a disposed [previous] transaction (with invalid handle) will be replaced by <see langword="null"/>. /// </remarks> public static KtmTransactionScope CreateLocal(bool dispose) { return(new KtmTransactionScope(KtmTransaction.BeginLocal(), dispose)); }
/// <summary> /// Create scope using the specified KTM transaction. /// </summary> /// <param name="transactionToUse"> /// Transaction instance to install into thread context; <see langword="null"/> allowed. /// </param> /// <param name="dispose"> /// Whether to dispose the <paramref name="transactionToUse"/> at the end of the scope. /// </param> /// <returns> /// <see cref="KtmTransactionScope"/> /// </returns> /// <remarks> /// The scope will install <paramref name="transactionToUse"/> as ambient, thread context transaction. At the end of the scope /// (when scope is disposed) the transaction will be disposed according to <paramref name="dispose"/> and thread context will be /// restored unless the <paramref name="transactionToUse"/> is already ambient at the start of the scope. /// Before disposing the transaction it will be committed if the <paramref name="transactionToUse"/> is not owned /// by a managed transaction (<see cref="IFileSystemTransaction.IsSlave"/>) and the scope has been marked as completed /// (<see cref="Complete()"/>) and the <paramref name="transactionToUse"/> is not null. /// When restoring context a disposed [previous] transaction (with invalid handle) will be replaced by <see langword="null"/>. /// </remarks> public static KtmTransactionScope Create(KtmTransaction transactionToUse, bool dispose) { return(new KtmTransactionScope(transactionToUse, dispose)); }