Ejemplo n.º 1
0
        /// roll back the transaction
        public void Rollback()
        {
            string         TransactionIdentifier     = null;
            bool           TransactionValid          = false;
            IsolationLevel TransactionIsolationLevel = IsolationLevel.Unspecified;

            // Attempt to roll back the DB Transaction.
            try
            {
                // 'Sanity Check': Check that TheTransaction hasn't been committed or rolled back yet.
                if (!Valid)
                {
                    var Exc1 =
                        new EDBAttemptingToUseTransactionThatIsInvalidException(
                            "TDataBase.RollbackTransaction called on DB Transaction that isn't valid",
                            ThreadingHelper.GetThreadIdentifier(ThreadThatTransactionWasStartedOn),
                            ThreadingHelper.GetCurrentThreadIdentifier());

                    TLogging.Log(Exc1.ToString());

                    throw Exc1;
                }

                if (TLogging.DL >= DBAccess.DB_DEBUGLEVEL_TRANSACTION_DETAIL)
                {
                    // Gather information for logging
                    TransactionIdentifier     = GetDBTransactionIdentifier();
                    TransactionValid          = Valid;
                    TransactionIsolationLevel = IsolationLevel;
                }

                WrappedTransaction.Rollback();

                TLogging.LogAtLevel(DBAccess.DB_DEBUGLEVEL_TRANSACTION, "       Transaction " + FTransactionName + " in Connection " + FTDataBaseInstanceThatTransactionBelongsTo.ConnectionName + " rolled back");

                // Rollback was OK, now clean up.
                Dispose();

                TLogging.LogAtLevel(DBAccess.DB_DEBUGLEVEL_TRANSACTION_DETAIL, String.Format(
                                        "DB Transaction{0} got rolled back.  Before that, its DB Transaction Properties were: Valid: {1}, " +
                                        "IsolationLevel: {2} (it got started on Thread {3} in AppDomain '{4}').", TransactionIdentifier,
                                        TransactionValid, TransactionIsolationLevel, ThreadThatTransactionWasStartedOn,
                                        AppDomainNameThatTransactionWasStartedIn)
                                    );
            }
            catch (Exception Exc)
            {
                // This catch block will handle any errors that may have occurred
                // on the server that would cause the rollback to fail, such as
                // a closed connection.
                //
                // MSDN says: "Try/Catch exception handling should always be used when rolling back a
                // transaction. A Rollback generates an InvalidOperationException if the connection is
                // terminated or if the transaction has already been rolled back on the server."
                TLogging.Log("Exception while attempting Transaction rollback: " + Exc.ToString());
            }
        }
Ejemplo n.º 2
0
            /// <summary>
            /// Performs an unlimited number of retries to (re-)establish the Server's DB Polling Connection.
            /// Finishes only when the Server's DB Polling Connection is restored.
            /// </summary>
            /// <remarks>This Method must only be run in a Thread as otherwise it would blocks the server
            /// completely!</remarks>
            public void PerformDBReconnection()
            {
                const int WAITING_TIME_BETWEEN_RETRIES = 2000; // 2000 Milliseconds

                string StrOpenDBConn        = Catalog.GetString("open the Server's DB Polling Connection...");
                string StrReestablishDBConn = Catalog.GetString("re-establish the Server's broken DB Polling Connection...");
                string StrEstablished       = Catalog.GetString("got successfully established");
                string StrRestored          = Catalog.GetString("got successfully restored");
                bool   DBConnectionRestored = false;

                FTheServerManager.DBReconnectionAttemptsCounter = 0;

                TLogging.LogAtLevel(1, String.Format(
                                        "ExceptionHandling_DBConnectionBrokenCallback: Starting handling of broken database connection (on Thread {0})...!",
                                        ThreadingHelper.GetThreadIdentifier(Thread.CurrentThread)));

                while (!DBConnectionRestored)
                {
                    try
                    {
                        FTheServerManager.DBReconnectionAttemptsCounter++;

                        TLogging.Log(String.Format("Attempt {0} to ", FTheServerManager.DBReconnectionAttemptsCounter) +
                                     (FDBConnectionEstablishmentAtStartup ? StrOpenDBConn : StrReestablishDBConn));

                        FTheServerManager.EstablishDBPollingConnection();

                        DBConnectionRestored = true;
                    }
                    catch (SocketException Exc)
                    {
                        TLogging.LogAtLevel(1, Exc.Message);

                        // Getting a SocketException here *is what can be expected* until the DB connection can be successfully
                        // established - hence we are 'swallowing' this particular Exception here on purpose!
                        Thread.Sleep(WAITING_TIME_BETWEEN_RETRIES);
                    }
                    catch (NpgsqlException Exc)
                    {
                        TLogging.LogAtLevel(1, Exc.Message);

                        // Getting a NpgsqlException here *is what can be expected* until the DB connection can be successfully
                        // established - hence we are 'swallowing' this particular Exception here on purpose!
                        Thread.Sleep(WAITING_TIME_BETWEEN_RETRIES);
                    }
                    catch (EDBConnectionNotEstablishedException Exc)
                    {
                        TLogging.LogAtLevel(1, Exc.Message);

                        // Getting an EDBConnectionNotEstablishedException here *is what can be expected* until the DB connection
                        // can be successfully established - hence we are 'swallowing' this particular Exception here on purpose!
                        Thread.Sleep(WAITING_TIME_BETWEEN_RETRIES);
                    }
                    catch (Exception Exc)
                    {
                        TLogging.Log(Exc.Message);
                        TLogging.LogStackTrace(TLoggingType.ToLogfile);

                        throw;
                    }
                }

                if (FCallbackAtEndOfThread != null)
                {
                    FCallbackAtEndOfThread(false, 0);
                }
                else
                {
                    throw new EOPException("Delegate 'FCallbackAtEndOfThread' was not set up, but it must be set up " +
                                           "for the ability of the 'PerformDBReconnection' Method to signalise that it has re-established the " +
                                           "Server's DB Polling Connection");
                }

                // Log that we are done once the Callback Method has finished running
                if (TLogging.DebugLevel == 0)
                {
                    TLogging.Log(String.Format("  --> The Server's DB Polling Connection {0}!",
                                               FDBConnectionEstablishmentAtStartup ? StrEstablished : StrRestored));
                }
                else
                {
                    TLogging.Log(
                        String.Format("FINISHED with the handling of a broken database " +
                                      "connection (on Thread {0}) - the Server's DB Polling Connection {1}!",
                                      ThreadingHelper.GetThreadIdentifier(Thread.CurrentThread),
                                      FDBConnectionEstablishmentAtStartup ? StrEstablished : StrRestored));
                }
            }