Ejemplo n.º 1
0
        Maybe <ICreatedTransaction> ITransactionManager.CreateTransaction(ITransactionOptions transactionOptions)
        {
            var activity = _activityManager.GetCurrentActivity();

            if (transactionOptions.Mode == TransactionScopeOption.Suppress)
            {
                return(Maybe.None <ICreatedTransaction>());
            }

            var nextStackDepth = activity.Count + 1;
            var shouldFork     = transactionOptions.ShouldFork(nextStackDepth);

            ITransaction tx;

            if (activity.Count == 0)
            {
                var committableTx = new CommittableTransaction(new TransactionOptions
                {
                    IsolationLevel = transactionOptions.IsolationLevel,
                    Timeout        = transactionOptions.Timeout
                });
                tx = new Transaction(committableTx, nextStackDepth, transactionOptions, () => activity.Pop(),
                                     _loggerFactory.CreateChildLogger("Transaction", GetType()));
            }
            else
            {
                var clone = activity
                            .CurrentTransaction.Value
                            .Inner
                            .DependentClone(transactionOptions.DependentOption);
                Contract.Assume(clone != null);

                Action onDispose = () => activity.Pop();
                tx = new Transaction(clone, nextStackDepth, transactionOptions, shouldFork ? null : onDispose,
                                     _loggerFactory.CreateChildLogger("Transaction", GetType()));
            }

            if (!shouldFork)             // forked transactions should not be on the current context's activity stack
            {
                activity.Push(tx);
            }

            Contract.Assume(tx.State == TransactionState.Active, "by c'tor post condition for both cases of the if statement");

            // we should only fork if we have a different current top transaction than the current
            var m = Maybe.Some(new CreatedTransaction(tx, shouldFork, this.ForkScopeFactory(tx)) as ICreatedTransaction);

            // warn if fork and the top transaction was just created
            if (transactionOptions.Fork && nextStackDepth == 1)
            {
                _logger.LogWarning("transaction {0} created with Fork=true option, but was top-most "
                                   + "transaction in invocation chain. running transaction sequentially",
                                   tx.LocalIdentifier);
            }

            Contract.Assume(m.HasValue && m.Value.Transaction.State == TransactionState.Active);

            return(m);
        }