/// <summary>
 /// Adds a row lock to the list of locks that must be released at the end of a transaction.
 /// </summary>
 /// <param name="enlistment">Facilitates communication bewtween an enlisted transaction participant and the transaction
 /// manager during the final phase of the transaction.</param>
 public void InDoubt(global::System.Transactions.Enlistment enlistment)
 {
     /*This method is called for volatile resources when the transaction manager has invoked a single phase commit
      * operation to a single durable resource,
      * and then connection to the durable resource was lost prior to getting the transaction result.
      * At that point, the transaction outcome cannot be safely determined.
      *	As InDoubt is considered to be a final state for a transaction, you should not call Commit or Rollback after calling InDoubt.
      */
     try
     {
         global::FluidTrade.Core.EventLog.Information("<<<***>>> DataModelTransaction InDoubt");
     }
     catch
     {
     }
     if (this.ClearRowLockList())
     {
         try
         {
             global::FluidTrade.Core.EventLog.Information("<<<***>>> DataModelTransaction InDoubt cleared rows in List");
         }
         catch
         {
         }
     }
 }
        /// <summary>
        /// Adds a row lock to the list of locks that must be released at the end of a transaction.
        /// </summary>
        /// <param name="enlistment">Facilitates communication bewtween an enlisted transaction participant and the transaction
        /// manager during the final phase of the transaction.</param>
        public void Rollback(global::System.Transactions.Enlistment enlistment)
        {
            this.recordList.Reverse();
            try
            {
                DataModel.DataLock.EnterWriteLock();
                for (int recordIndex = 0; (recordIndex < this.recordList.Count); recordIndex = (recordIndex + 1))
                {
                    global::FluidTrade.Core.IRow iRow = this.recordList[recordIndex];
                    if (((iRow.RowState == global::System.Data.DataRowState.Added) ||
                         ((iRow.RowState == global::System.Data.DataRowState.Deleted) ||
                          (iRow.RowState == global::System.Data.DataRowState.Modified))))
                    {
                        iRow.RejectChanges();
                    }
                }
            }
            finally
            {
                this.ClearRowLockList();

                DataModel.DataLock.ExitWriteLock();
                try
                {
                    //txn is done remove this txn from the threads stack
                    //in theory the stack should only be accessed from the same thread so dont need a lock
                    //although might want to look at the stack through the DataModelTransaction
                    //via another thread. so lock just to be safe
                    lock (this.dataModelTransactionStack)
                        this.dataModelTransactionStack.Pop();
                }
                catch (Exception ex)
                {
                    try
                    {
                        global::FluidTrade.Core.EventLog.Information("Error in Commit dataModelTransactionStack.Pop {0}\r\n{1}", ex.Message, ex.StackTrace);
                    }
                    catch
                    {
                    }
                }
            }
            enlistment.Done();
        }
        /// <summary>
        /// Adds a row lock to the list of locks that must be released at the end of a transaction.
        /// </summary>
        /// <param name="enlistment">Facilitates communication bewtween an enlisted transaction participant and the transaction
        /// manager during the final phase of the transaction.</param>
        public void Commit(global::System.Transactions.Enlistment enlistment)
        {
            try
            {
                global::System.Collections.Generic.List <object> transactionLogItem = new global::System.Collections.Generic.List <object>();
                DataModel.TransactionLogLock.EnterWriteLock();
                DataModel.DataLock.EnterWriteLock();
                for (int recordIndex = 0; (recordIndex < this.recordList.Count); recordIndex = (recordIndex + 1))
                {
                    global::FluidTrade.Core.IRow   iRow   = this.recordList[recordIndex];
                    global::FluidTrade.Core.ITable iTable = ((global::FluidTrade.Core.ITable)(iRow.Table));
                    if ((iRow.RowState == global::System.Data.DataRowState.Modified))
                    {
                        transactionLogItem.Clear();
                        transactionLogItem.Add(global::FluidTrade.Core.RecordState.Modified);
                        transactionLogItem.Add(iTable.Ordinal);
                        for (int keyIndex = 0; (keyIndex < iTable.PrimaryKey.Length); keyIndex = (keyIndex + 1))
                        {
                            transactionLogItem.Add(iRow[iTable.PrimaryKey[keyIndex]]);
                        }
                        for (int columnIndex = 0; (columnIndex < iTable.Columns.Count); columnIndex = (columnIndex + 1))
                        {
                            if ((iRow[columnIndex].Equals(iRow[columnIndex, global::System.Data.DataRowVersion.Original]) == false))
                            {
                                transactionLogItem.Add(columnIndex);
                                transactionLogItem.Add(iRow[columnIndex]);
                            }
                        }
                        DataModel.AddTransaction(iRow, transactionLogItem.ToArray());
                        iRow.AcceptChanges();
                    }
                    else
                    {
                        if ((iRow.RowState == global::System.Data.DataRowState.Added))
                        {
                            transactionLogItem.Clear();
                            transactionLogItem.Add(global::FluidTrade.Core.RecordState.Added);
                            transactionLogItem.Add(iTable.Ordinal);
                            for (int keyIndex = 0; (keyIndex < iTable.PrimaryKey.Length); keyIndex = (keyIndex + 1))
                            {
                                transactionLogItem.Add(iRow[iTable.PrimaryKey[keyIndex]]);
                            }
                            for (int columnIndex = 0; (columnIndex < iTable.Columns.Count); columnIndex = (columnIndex + 1))
                            {
                                if ((iRow[columnIndex].Equals(iTable.Columns[columnIndex].DefaultValue) == false))
                                {
                                    transactionLogItem.Add(columnIndex);
                                    transactionLogItem.Add(iRow[columnIndex]);
                                }
                            }
                            DataModel.AddTransaction(iRow, transactionLogItem.ToArray());
                            iRow.AcceptChanges();
                        }
                        else
                        {
                            transactionLogItem.Clear();
                            transactionLogItem.Add(global::FluidTrade.Core.RecordState.Deleted);
                            transactionLogItem.Add(iTable.Ordinal);
                            for (int keyIndex = 0; (keyIndex < iTable.PrimaryKey.Length); keyIndex = (keyIndex + 1))
                            {
                                transactionLogItem.Add(iRow[iTable.PrimaryKey[keyIndex], global::System.Data.DataRowVersion.Original]);
                            }
                            DataModel.AddTransaction(iRow, transactionLogItem.ToArray());
                            iRow.AcceptChanges();
                        }
                    }
                }
            }
            finally
            {
                ClearRowLockList();

                DataModel.TransactionLogLock.ExitWriteLock();
                DataModel.DataLock.ExitWriteLock();

                try
                {
                    //txn is done remove this txn from the threads stack
                    //in theory the stack should only be accessed from the same thread so dont need a lock
                    //although might want to look at the stack through the DataModelTransaction
                    //via another thread. so lock just to be safe
                    lock (this.dataModelTransactionStack)
                        this.dataModelTransactionStack.Pop();
                }
                catch (Exception ex)
                {
                    try
                    {
                        global::FluidTrade.Core.EventLog.Information("Error in Commit dataModelTransactionStack.Pop {0}\r\n{1}", ex.Message, ex.StackTrace);
                    }
                    catch
                    {
                    }
                }
            }
            enlistment.Done();
        }