private IUnitOfWork GetRequiredUnitOfWork(PersistenceOptions persistenceOptions) { if (!AmbientContextManager.AmbientExists) { return(GetRequiredNewUnitOfWork(persistenceOptions)); } if (!AmbientContextManager.Ambient.IsTypeOf <CompositeUnitOfWork>()) { throw NContextPersistenceError.CompositeUnitOfWorkWithinDifferentAmbientType(AmbientContextManager.Ambient.UnitOfWork.GetType()) .ToException <InvalidOperationException>(); } // TODO: (DG) If ambient is a Composite do we retain or add to it? //if () //{ // var currentCompositeUnitOfWork = (CompositeUnitOfWork)AmbientContextManager.Ambient.UnitOfWork; // unitOfWork = new CompositeUnitOfWork(AmbientContextManager, currentCompositeUnitOfWork, _PersistenceOptions); // currentCompositeUnitOfWork.AddUnitOfWork(unitOfWork); // AmbientContextManager.AddUnitOfWork(unitOfWork); //} AmbientContextManager.RetainAmbient(); return(AmbientContextManager.Ambient.UnitOfWork); }
private IUnitOfWork GetRequiredNewUnitOfWork(PersistenceOptions persistenceOptions) { UnitOfWorkBase unitOfWork = new CompositeUnitOfWork(AmbientContextManager, persistenceOptions); AmbientContextManager.AddUnitOfWork(unitOfWork); return(unitOfWork); }
private IUnitOfWork GetRequiredNewUnitOfWork(TransactionOptions transactionOptions) { var unitOfWork = new EfUnitOfWork(AmbientContextManager, new DbContextContainer()); AmbientContextManager.AddUnitOfWork(unitOfWork); return(unitOfWork); }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposeManagedResources"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected virtual void Dispose(Boolean disposeManagedResources) { if (IsDisposed) { return; } if (disposeManagedResources && AmbientContextManager.CanDisposeUnitOfWork(this)) { DisposeManagedResources(); IsDisposed = true; } }
private IServiceResponse <Unit> CommitChildrenParallel() { if (!AmbientContextManager.IsThreadSafe) { return(NContextPersistenceError.ConcurrencyUnsupported(AmbientContextManager.GetType()).ToServiceResponse()); } var commitExceptions = new ConcurrentQueue <Error>(); Parallel.ForEach( UnitsOfWork, new ParallelOptions { MaxDegreeOfParallelism = _PersistenceOptions.MaxDegreeOfParallelism }, (unitOfWork, state) => { try { if (state.IsExceptional || state.ShouldExitCurrentIteration) { return; } unitOfWork.Commit() .Catch(error => { state.Break(); commitExceptions.Enqueue(error); }); } catch (Exception exception) { state.Break(); commitExceptions.Enqueue(exception.ToError()); // TODO: (DG) Logging ... } }); return(commitExceptions.Any() ? (IServiceResponse <Unit>) new ErrorResponse <Unit>(new AggregateError((Int32)HttpStatusCode.InternalServerError, GetType().Name, commitExceptions.Select(error => error))) : (IServiceResponse <Unit>) new DataResponse <Unit>(default(Unit))); }
private IUnitOfWork GetRequiredUnitOfWork(TransactionOptions transactionOptions) { if (!AmbientContextManager.AmbientExists || !AmbientContextManager.AmbientUnitOfWorkIsValid) { return(GetRequiredNewUnitOfWork(transactionOptions)); } /* First check if the ambient is a CompositeUnitOfWork and add to its collection. * This must come prior to checking whether it is not an instance of IEfUnitOfWork so we can * add it as a leaf to a composite. * */ var ambient = AmbientContextManager.Ambient; if (ambient.IsTypeOf <CompositeUnitOfWork>()) { UnitOfWorkBase unitOfWork; var currentCompositeUnitOfWork = (CompositeUnitOfWork)AmbientContextManager.Ambient.UnitOfWork; if (currentCompositeUnitOfWork.ContainsType <IEfUnitOfWork>()) { unitOfWork = currentCompositeUnitOfWork.Single(uow => uow.GetType().Implements <IEfUnitOfWork>()); } else { unitOfWork = new EfUnitOfWork(AmbientContextManager, new DbContextContainer(), currentCompositeUnitOfWork); currentCompositeUnitOfWork.Add(unitOfWork); } AmbientContextManager.AddUnitOfWork(unitOfWork); return(unitOfWork); } // Current ambient is not Entity Framework. if (!AmbientContextManager.Ambient.IsTypeOf <IEfUnitOfWork>()) { return(GetRequiredNewUnitOfWork(transactionOptions)); } // Current ambient implements IEfUnitOfWork so let's simply retain it by incrementing the ambient session count. AmbientContextManager.RetainAmbient(); return(AmbientContextManager.Ambient.UnitOfWork); }
/// <summary> /// Commits the changes to the database. /// </summary> /// <returns>IServiceResponse{Boolean}.</returns> /// <exception cref="System.InvalidOperationException"></exception> public IServiceResponse <Unit> Commit() { if (Status == TransactionStatus.Active) { throw new InvalidOperationException(String.Format(LocalizedPersistenceError.UnitOfWorkCommitting, Id)); } if (Status == TransactionStatus.Committed) { throw new InvalidOperationException(String.Format(LocalizedPersistenceError.UnitOfWorkCommitted, Id)); } if (!AmbientContextManager.CanCommitUnitOfWork(this)) { return(NContextPersistenceError.UnitOfWorkNonCommittable(Id).ToServiceResponse()); } if (ScopeTransaction == null) { return(NContextPersistenceError.ScopeTransactionIsNull().ToServiceResponse()); } TransactionScope transactionScope = null; if (Parent == null && ScopeThread == Thread.CurrentThread) { // Use the existing CurrentTransaction. _CurrentTransactionFactory = new Lazy <Transaction>(() => ScopeTransaction); transactionScope = new TransactionScope(CurrentTransaction, TransactionOptions.Timeout); } else if (ScopeThread != Thread.CurrentThread) { // UnitOfWork is being committed on a different thread. _CurrentTransactionFactory = new Lazy <Transaction>(() => ScopeTransaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete)); transactionScope = new TransactionScope(CurrentTransaction, TransactionOptions.Timeout); } _Status = TransactionStatus.Active; return(CommitTransaction(transactionScope) .Catch(_ => { _Status = TransactionStatus.Aborted; }) .Bind(_ => { _Status = TransactionStatus.Committed; if (CurrentTransaction is DependentTransaction) { if (transactionScope != null) { transactionScope.Complete(); transactionScope.Dispose(); } var dependentTransaction = CurrentTransaction as DependentTransaction; dependentTransaction.Complete(); dependentTransaction.Dispose(); } else if (CurrentTransaction is CommittableTransaction) { try { (CurrentTransaction as CommittableTransaction).Commit(); } catch (TransactionAbortedException abortedException) { return NContextPersistenceError.CommitFailed(Id, CurrentTransaction.TransactionInformation.LocalIdentifier, abortedException) .ToServiceResponse(); } } return new DataResponse <Unit>(default(Unit)); })); }