예제 #1
0
        /// <summary>
        /// This method can run synchronous as well as asynchronous operations within a transaction
        /// in the order in which the operations are written in the consumer class.Here synchronous
        /// as well as asynchronous operations are hadnled since "Task" also inherently handles both
        /// synchronous and asynchronous scenarios.
        ///
        /// </summary>
        /// <param name="shouldCommitSynchronousOperationsFirst"></param>
        /// <param name="shouldAutomaticallyRollBackOnTransactionException"></param>
        /// <param name="shouldThrowOnException"></param>
        /// <returns></returns>
        public async Task CommitAsync(CancellationToken token = default(CancellationToken), bool shouldAutomaticallyRollBackOnTransactionException = true, bool shouldThrowOnException = true)
        {
            CheckForObjectAlreadyDisposedOrNot(typeof(UnitOfWork).FullName);
            ContractUtility.Requires <ArgumentOutOfRangeException>(_operationsQueue.Count > 0, "Atleast one operation must be there to be executed.");
            ContractUtility.Requires <NotSupportedException>(_operationsQueue.Any(x => x.AsyncOperation.IsNotNull()),
                                                             "If CommitAsync method is used,there needs to be atleast one async operation exceuted." +
                                                             "Please use Commit method(instead of CommitAsync) if there is not " +
                                                             "a single async operation.");

            await ExceptionHandlingUtility.HandleExceptionWithNullCheck(async x =>
            {
                _scope = TransactionUtility.GetTransactionScope(_isoLevel, _scopeOption, true);
                try
                {
                    while (_operationsQueue.Count > 0)
                    {
#if TEST
                        ThrowExceptionForRollbackCheck();
#endif
                        OperationData operationData = _operationsQueue.Dequeue();
                        if (operationData.Operation.IsNotNull())
                        {
                            operationData.Operation();
                        }
                        else if (operationData.AsyncOperation.IsNotNull())
                        {
                            await operationData.AsyncOperation(x);
                        }
                    }
                    CompleteScope(() =>
                    {
                        _scope.Complete(); // this just completes the transaction.Not yet committed here.
                        _scope.Dispose();  // After everthing runs successfully within the transaction
                                           // and after completion, this should be called to actually commit the data
                                           // within the transaction scope.
                    }, shouldAutomaticallyRollBackOnTransactionException, shouldThrowOnException);
                }
                catch (Exception ex)
                {
                    //Although ex is not exactly a commit exception but still passing it to reuse Rollback method.Using the Rollback
                    //method to reuse exception handling and dispose the transaction scope object(else it can cause issues for the
                    //future transactions).
                    Rollback(ex);
                }
            }, token, _exceptionHandler, null);//TODO - proper exception handling compensating handler needs to be here
        }
예제 #2
0
        /// <summary>
        /// Comits all the data within this unit of work instance in an atomic way i.e. all or none get transacted.
        /// Order of operations of different instances of same type or different types needs to be handled at
        /// the Business or Service Layer.
        /// </summary>
        /// <param name="shouldAutomaticallyRollBackOnTransactionException">when set to true(default value)
        /// the RollBack method need not be called from the consumer class</param>
        public void Commit(bool shouldAutomaticallyRollBackOnTransactionException = true, bool shouldThrowOnException = true)
        {
            ContractUtility.Requires <ArgumentOutOfRangeException>(_operationsQueue.IsNotNullOrEmpty(), "Atleast one operation must be there to be executed.");

            ContractUtility.Requires <NotSupportedException>(_operationsQueue.All(x => x.AsyncOperation.IsNull()),
                                                             "Async operations are not supported by Commit method.Use CommitAsync instead.");

            ExceptionHandlingUtility.HandleExceptionWithNullCheck(() =>
            {
                _scope = TransactionUtility.GetTransactionScope(_isoLevel, _scopeOption);
                try
                {
                    while (_operationsQueue.Count > 0)
                    {
#if TEST
                        ThrowExceptionForRollbackCheck();
#endif
                        OperationData operationData = _operationsQueue.Dequeue();
                        if (operationData.Operation.IsNotNull())
                        {
                            operationData.Operation();
                        }
                    }
                    CompleteScope(() =>
                    {
                        _scope.Complete(); // this just completes the transaction.Not yet committed here.
                        _scope.Dispose();  // After everthing runs successfully within the transaction
                                           // and after completion, this should be called to actually commit the data
                                           // within the transaction scope.
                    }, shouldAutomaticallyRollBackOnTransactionException, shouldThrowOnException);
                }
                catch (Exception ex)
                {
                    //Although ex is not exactly a commit exception but still passing it to reuse Rollback method.Using the Rollback
                    //method to reuse exception handling and dispose the transaction scope object(else it can cause issues for the
                    //future transactions).
                    Rollback(ex);
                }
            }, _exceptionHandler);//TODO - proper exception handling compensating handler needs to be here
        }