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.Fork && nextStackDepth > 1;

			ITransaction tx;
			if (activity.Count == 0)
			{
				tx = new Transaction(new CommittableTransaction(new TransactionOptions
				                                                	{
				                                                		IsolationLevel = transactionOptions.IsolationLevel,
				                                                		Timeout = transactionOptions.Timeout
				                                                	}), nextStackDepth, transactionOptions, () => activity.Pop());
			}
			else
			{
				var clone = activity
					.CurrentTransaction.Value
					.Inner
					.DependentClone(DependentCloneOption.BlockCommitUntilComplete);

				// assume because I can't open up .Net and add the contract myself
				Contract.Assume(clone != null);
				Action onDispose = () => activity.Pop();
				tx = new Transaction(clone, nextStackDepth, transactionOptions, shouldFork ? null : onDispose);
			}

			if (!shouldFork)
				activity.Push(tx);

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

			var m = Maybe.Some(new CreatedTransaction(tx,
			                                          // we should only fork if we have a different current top transaction than the current
			                                          shouldFork, () =>
			                                                      	{
			                                                      		_ActivityManager.GetCurrentActivity().Push(tx);
			                                                      		return
			                                                      			new DisposableScope(
			                                                      				_ActivityManager.GetCurrentActivity().Pop);
			                                                      	}) as ICreatedTransaction);

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

			// assume because I can't make value types and reference types equal enough
			// and boxing doesn't do it for me.
			Contract.Assume(m.HasValue && m.Value.Transaction.State == TransactionState.Active);

			return m;
		}
Example #2
0
		public FileTransaction(string name, DependentTransaction inner, uint stackDepth, ITransactionOptions creationOptions,
		                       Action onDispose)
		{
			Contract.Requires(inner != null);
			Contract.Requires(creationOptions != null);

			_Inner = new Transaction(inner, stackDepth, creationOptions, onDispose);

			_Name = name;
			InnerBegin();
		}
		public FileTransaction(string name, CommittableTransaction inner, uint stackDepth, ITransactionOptions creationOptions,
		                       Action onDispose)
		{
			Contract.Requires(inner != null);
			Contract.Requires(creationOptions != null);

			_Inner = new Transaction(inner, stackDepth, creationOptions, onDispose, NullLogger.Instance);

			_Name = name;
			InnerBegin();
		}
		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.Fork && nextStackDepth > 1;

			ITransaction tx;
			if (activity.Count == 0)
				tx = new Transaction(new CommittableTransaction(new TransactionOptions
				{
					IsolationLevel = transactionOptions.IsolationLevel,
					Timeout = transactionOptions.Timeout
				}), nextStackDepth, transactionOptions, () => activity.Pop(), logger.CreateChildLogger("Transaction"));
			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,
				                     logger.CreateChildLogger("Transaction"));
			}

			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");

			var m = Maybe.Some(new CreatedTransaction(tx,
				shouldFork, // we should only fork if we have a different current top transaction than the current
				() => {
					activityManager.GetCurrentActivity().Push(tx);
					return new DisposableScope(activityManager.GetCurrentActivity().Pop);
				}) as ICreatedTransaction);

			// warn if fork and the top transaction was just created
			if (transactionOptions.Fork && nextStackDepth == 1 && logger.IsWarnEnabled)
				logger.WarnFormat("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;
		}
		public FileTransaction(string name, CommittableTransaction inner, uint stackDepth, ITransactionOptions creationOptions,
		                       Action onDispose)
		{
			Contract.Requires(inner != null);
			Contract.Requires(creationOptions != null);
			Contract.Requires(!string.IsNullOrEmpty(name));
			Contract.Ensures(_Name != null);

			_Inner = new Transaction(inner, stackDepth, creationOptions, onDispose);

			_Name = name;
			InnerBegin();
		}
Example #6
0
		public Transaction(DependentTransaction dependent, uint stackDepth, ITransactionOptions creationOptions, Action onDispose)
		{
			Contract.Requires(creationOptions != null);
			Contract.Requires(dependent != null);
			Contract.Ensures(_State == TransactionState.Active);
			Contract.Ensures(((ITransaction)this).State == TransactionState.Active);

			_Dependent = dependent;
			_CreationOptions = creationOptions;
			_OnDispose = onDispose;
			_State = TransactionState.Active;
			_LocalIdentifier = dependent.TransactionInformation.LocalIdentifier + ":" + stackDepth;
		}
		public static Maybe<IFileTransaction> CreateFileTransaction(this ITransactionManager transactionManager, ITransactionOptions transactionOptions)
		{
			if (transactionOptions.Fork)
				throw new NotImplementedException("forking file transactions not implemented");

			// TODO: we need to decide what transaction manager we want running the show and be smarter about this:
			var activity = transactionManager.Activities.GetCurrentActivity();
			IFileTransaction tx = new FileTransaction();
			var fork = transactionOptions.ShouldFork(activity.Count + 1);
			if (!fork) activity.Push(tx);
			return Maybe.Some(tx);
			//return new CreatedTransaction(tx, fork, transactionManager.ForkScopeFactory(tx));
		}
		public Transaction(CommittableTransaction inner, uint stackDepth, ITransactionOptions creationOptions,
		                   Action onDispose)
		{
			Contract.Requires(creationOptions != null);
			Contract.Requires(inner != null);
			Contract.Ensures(_Inner != null);
			Contract.Ensures(_State == TransactionState.Active);
			Contract.Ensures(((ITransaction) this).State == TransactionState.Active);
			_Inner = inner;
			_StackDepth = stackDepth;
			_CreationOptions = creationOptions;
			_OnDispose = onDispose;
			_State = TransactionState.Active;
		}
Example #9
0
		public Transaction(CommittableTransaction committable, uint stackDepth, ITransactionOptions creationOptions,
		                   Action onDispose)
		{
			Contract.Requires(creationOptions != null);
			Contract.Requires(committable != null);
			Contract.Ensures(_State == TransactionState.Active);
			Contract.Ensures(((ITransaction)this).State == TransactionState.Active);

			_Committable = committable;
			_CreationOptions = creationOptions;
			_OnDispose = onDispose;
			_State = TransactionState.Active;
			_LocalIdentifier = committable.TransactionInformation.LocalIdentifier + ":" + stackDepth;
		}
		public Maybe<ICreatedTransaction> CreateTransaction(ITransactionOptions transactionOptions)
		{
			Contract.Requires(transactionOptions != null);

			Contract.Ensures(Contract.Result<Maybe<ICreatedTransaction>>() != null
			                 && (!Contract.Result<Maybe<ICreatedTransaction>>().HasValue
			                     ||
			                     Contract.Result<Maybe<ICreatedTransaction>>().Value.Transaction.State == TransactionState.Active));

			Contract.Ensures(Contract.Result<Maybe<ICreatedTransaction>>().HasValue
			                 || transactionOptions.Mode == TransactionScopeOption.Suppress);

			throw new NotImplementedException();
		}
		public FileTransaction(string name, DependentTransaction inner, uint stackDepth, ITransactionOptions creationOptions,
								Action onDispose, ILogger logger)
		{
			Contract.Requires(inner != null);
			Contract.Requires(creationOptions != null);
			Contract.Requires(!string.IsNullOrEmpty(name));
			Contract.Requires(logger != null);
			Contract.Ensures(_Name != null);

			_Inner = new Transaction(inner, stackDepth, creationOptions, onDispose, logger.CreateChildLogger("Transaction"));

			_Name = name;
			InnerBegin();
		}
		Maybe<ICreatedTransaction> ITransactionManager.CreateFileTransaction(ITransactionOptions transactionOptions)
		{
			throw new NotImplementedException("Implement file transactions in the transaction manager!");
		}
		public static Maybe<ITransaction> CreateFileTransaction(this ITransactionManager manager,
		                                                        ITransactionOptions options)
		{
			throw new NotImplementedException();
		}
		public bool Equals(ITransactionOptions other)
		{
			if (ReferenceEquals(null, other)) return false;
			if (ReferenceEquals(this, other)) return true;

			return Equals(other.IsolationLevel, IsolationLevel)
			       && Equals(other.Mode, Mode)
			       && other.Fork.Equals(Fork)
			       && other.Timeout.Equals(Timeout)
			       && other.CustomContext.All(x => _CustomContext.ContainsKey(x.Key) && _CustomContext[x.Key].Equals(x.Value))
			       && other.AsyncRollback.Equals(AsyncRollback)
			       && other.AsyncCommit.Equals(AsyncCommit);
		}
		public bool Equals(ITransactionOptions other)
		{
			if (ReferenceEquals(null, other)) return false;
			if (ReferenceEquals(this, other)) return true;

			return Equals(other.IsolationLevel, IsolationLevel)
			       && Equals(other.Mode, Mode)
			       && other.Fork.Equals(Fork)
			       && other.Timeout.Equals(Timeout)
			       && other.AsyncRollback.Equals(AsyncRollback)
			       && other.AsyncCommit.Equals(AsyncCommit);
		}