Пример #1
0
        /// <summary>
        /// Begin transaction
        /// </summary>
        /// <param name="parentTransaction">Parent Transaction that begin this transaction</param>
        /// <returns>DataAccessTransactionDb transaction object</returns>
        public DataAccessTransactionDb BeginTransaction(Transaction parentTransaction)
        {
            CheckState();

            var transaction = new DataAccessTransactionDb(this, parentTransaction);

            transactions.Push(transaction);

            return(transaction);
        }
Пример #2
0
        /// <summary>
        /// Commit transaction
        /// </summary>
        /// <param name="transaction">DataAccessTransactionDb transaction object for commit</param>
        internal void CommitTransaction(DataAccessTransactionDb transaction)
        {
            if (transactions.Count == 0)
            {
                throw new TransactionException("There is no started transactions");
            }

            if (transactions.First() != transaction)
            {
                throw new TransactionException("This is not last started transaction");
            }



            if (transactions.Count == 1)
            {
                // This is last DataAccess Transaction. Commit real db transaction, if it`s exists
                if (dbTransaction != null)
                {
                    // Уведомляем основное соединение о начале физического коммита
                    if (transaction.ParentTransaction != null)
                    {
                        transaction.ParentTransaction.Connection.OnPhysicalCommit();
                    }

                    var tmpTransaction = dbTransaction;
                    var tmpConnection  = dbTransaction.Connection;
                    dbTransaction = null;

                    try
                    {
                        tmpTransaction.Commit();
                        tmpConnection.Close();
                    }
                    catch (Exception ex)
                    {
                        // Принудительное закрытие соединения без проброса ошибки
                        // использовать просто using для вызова Dispose нельзя так как если будет ошибка
                        // при вызове Dispose в using то наш Exception не дойдет
                        // https://msdn.microsoft.com/ru-ru/library/aa355056%28v=vs.110%29.aspx
                        try { tmpConnection.Dispose(); } catch { }

                        throw new TransactionUnknowStateException(ex.Message, ex);
                    }
                }
            }

            transactions.Pop();
        }
Пример #3
0
        /// <summary>
        /// Create command object
        /// </summary>
        /// <param name="transaction">Transaction object</param>
        /// <param name="sql">Sql query</param>
        /// <param name="parameters">List of Parameters. Can used specific parameters also as SqlParameter, etc</param>
        /// <param name="isStoredProcedure">True if sql is stored procedure</param>
        /// <returns>DbCommand object</returns>
        private DbCommand CreateCommand(DataAccessTransactionDb transaction, string sql, IList <DbParameter> parameters, bool isStoredProcedure)
        {
            DbCommand dbCommand = dbProviderFactory.CreateCommand();

            dbCommand.CommandText = sql;
            dbCommand.Connection  = transaction.DbTransaction.Connection;
            dbCommand.Transaction = transaction.DbTransaction;


            if (isStoredProcedure)
            {
                dbCommand.CommandType = CommandType.StoredProcedure;
            }

            if (parameters != null)
            {
                foreach (var parameter in parameters)
                {
                    dbCommand.Parameters.Add(parameter);
                }
            }

            return(dbCommand);
        }
Пример #4
0
        /// <summary>
        /// Rollback transaction
        /// </summary>
        /// <param name="transaction">DataAccessTransactionDb transaction object for rollback</param>
        internal void RollbackTransactions(DataAccessTransactionDb transaction)
        {
            // Сохраняем первое исключение
            Exception firstException = null;

            // Rollback real db transaction
            if (dbTransaction != null)
            {
                var tmpTransaction = dbTransaction;
                var tmpConnection  = dbTransaction.Connection;
                dbTransaction = null;

                try
                {
                    if (tmpTransaction != null)
                    {
                        tmpTransaction.Rollback();
                    }
                    if (tmpConnection != null)
                    {
                        tmpConnection.Close();
                    }
                }
                catch (Exception ex)
                {
                    if (firstException == null)
                    {
                        firstException = ex;
                    }

                    // Принудительное закрытие соединения без проброса ошибки
                    // использовать просто using для вызова Dispose нельзя так как если будет ошибка
                    // при вызове Dispose в using то наш Exception не дойдет
                    // https://msdn.microsoft.com/ru-ru/library/aa355056%28v=vs.110%29.aspx
                    try { tmpConnection.Dispose(); } catch { }
                }
            }


            // Rollback all runned transactions
            if (TransactionsCount > 0)
            {
                var transactionsToRollback = transactions;
                transactions = new Stack <DataAccessTransactionDb>();

                foreach (var item in transactionsToRollback)
                {
                    try
                    {
                        item.Rollback();

                        if (item.ParentTransaction != null)
                        {
                            item.ParentTransaction.Rollback();
                        }
                    }
                    catch (Exception ex)
                    {
                        if (firstException == null)
                        {
                            firstException = ex;
                        }
                    }
                }
            }

            if (firstException != null)
            {
                throw new TransactionUnknowStateException(firstException.Message, firstException);
            }
        }