Exemplo n.º 1
0
 public SQLExtDataReader(DbCommand cmd, CommandBehavior behaviour, SQLExtTransaction <TConn> txn = null, SQLExtTransactionLock <TConn> txnlock = null)
 {
     this.command     = cmd;
     this.InnerReader = cmd.ExecuteReader(behaviour);
     this.transaction = txn;
     this.txnlock     = txnlock;
 }
        private static void DebugLongRunningOperation(SQLExtTransactionLock <TConn> txnlock)
        {
            if (txnlock != null)
            {
                txnlock.isLongRunning = true;

                if (txnlock.commandExecuting)
                {
                    if (txnlock.isLongRunning)
                    {
                        Trace.WriteLine($"{Environment.TickCount % 10000} The following command is taking a long time to execute:\n{txnlock.commandText}");
                    }
                    if (txnlock.owningThread == Thread.CurrentThread)
                    {
                        StackTrace trace = new StackTrace(1, true);
                        Trace.WriteLine(trace.ToString());
                    }
                }
                else
                {
                    Trace.WriteLine($"{Environment.TickCount % 10000} The transaction lock has been held for a long time.");

                    if (txnlock.commandText != null)
                    {
                        Trace.WriteLine($"{Environment.TickCount % 10000} Last command to execute:\n{txnlock.commandText}");
                    }
                }
            }
        }
        // disposing: true if Dispose() was called, false
        // if being finalized by the garbage collector
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (connection != null)
                {
                    //   System.Diagnostics.Debug.WriteLine("Closed connection " + connection.ConnectionString);
                    connection.Close();
                    connection.Dispose();
                    connection = null;
                }

                if (schemaLock.IsReadLockHeld)
                {
                    schemaLock.ExitReadLock();
                }

                if (transactionLock != null)
                {
                    transactionLock.Dispose();
                    transactionLock = null;
                }
            }

            base.Dispose(disposing);
        }
Exemplo n.º 4
0
        public override void Close()
        {
            InnerReader.Close();

            if (txnlock != null)
            {
                txnlock.CloseReader();
                txnlock = null;
            }
        }
Exemplo n.º 5
0
 public SQLExtCommand(DbCommand cmd, SQLExtConnection conn, SQLExtTransactionLock <TConn> txnlock, DbTransaction txn = null)
 {
     connection   = conn;
     this.txnlock = txnlock;
     InnerCommand = cmd;
     if (txn != null)
     {
         SetTransaction(txn);
     }
 }
        private static void DebugLongRunningOperation(object state)
        {
            WeakReference weakref = state as WeakReference;

            if (weakref != null)
            {
                SQLExtTransactionLock <TConn> txnlock = weakref.Target as SQLExtTransactionLock <TConn>;

                DebugLongRunningOperation(txnlock);
            }
        }
        public SQLExtConnectionWithLock(string dbfile, bool utctimeindicator, Action initializercallback = null, AccessMode mode = AccessMode.ReaderWriter)  : base(mode)
        {
            bool locktaken = false;

            try
            {
                if (initializercallback != null && !IsInitialized)
                {
                    System.Diagnostics.Trace.WriteLine($"Database {typeof(TConn).Name} initialized before Initialize()");
                    System.Diagnostics.Trace.WriteLine(new System.Diagnostics.StackTrace(2, true).ToString());

                    initializercallback();  // call back up to initialise
                }

                schemaLock.EnterReadLock();
                locktaken = true;

                // System.Threading.Monitor.Enter(monitor);
                DBFile     = dbfile;
                connection = DbFactory.CreateConnection();

                // Use the database selected by maindb as the 'main' database
                connection.ConnectionString = "Data Source=" + DBFile.Replace("\\", "\\\\") + ";Pooling=true;";

                if (utctimeindicator)   // indicate treat dates as UTC.
                {
                    connection.ConnectionString += "DateTimeKind=Utc;";
                }

                // System.Diagnostics.Debug.WriteLine("Created connection " + connection.ConnectionString);

                transactionLock = new SQLExtTransactionLock <TConn>();
                connection.Open();
            }
            catch
            {
                if (transactionLock != null)
                {
                    transactionLock.Dispose();
                }

                if (locktaken)
                {
                    schemaLock.ExitReadLock();
                }
                throw;
            }
        }
        public void OpenReader()
        {
            if (owningThread != Thread.CurrentThread)
            {
                throw new InvalidOperationException("Transaction lock passed between threads");
            }

            if (!rwlock.IsWriteLockHeld)
            {
                if (!isReader)
                {
                    try
                    {
                        Interlocked.Increment(ref readsWaiting);
                        bool warned = false;
                        while (!rwlock.TryEnterReadLock(1000))
                        {
                            SQLExtTransactionLock <TConn> lockowner = writeLockOwner;
                            if (lockowner != null)
                            {
                                warned = true;
                                Trace.WriteLine($"{Environment.TickCount % 10000} Thread {Thread.CurrentThread.Name} waiting for thread {lockowner.owningThread.Name} to finish writer");
                                DebugLongRunningOperation(lockowner);
                            }
                        }

                        if (warned)
                        {
                            Trace.WriteLine($"{Environment.TickCount % 10000} Thread {Thread.CurrentThread.Name} Released for read");
                        }

                        isReader = true;
                    }
                    finally
                    {
                        Interlocked.Decrement(ref readsWaiting);
                    }
                }
            }
        }
Exemplo n.º 9
0
 public SQLExtTransaction(DbTransaction txn, SQLExtTransactionLock <TConn> txnlock)
 {
     transactionLock  = txnlock;
     InnerTransaction = txn;
 }
Exemplo n.º 10
0
        public SQLExtConnectionWithLock(string dbfile, bool utctimeindicator, Action initializercallback = null, AccessMode mode = AccessMode.ReaderWriter)  : base(mode)
        {
            bool locktaken = false;

            try
            {
                if (initializercallback != null && !IsInitialized)
                {
                    System.Diagnostics.Trace.WriteLine($"Database {typeof(TConn).Name} initialized before Initialize()");
                    System.Diagnostics.Trace.WriteLine(new System.Diagnostics.StackTrace(2, true).ToString());

                    initializercallback();  // call back up to initialise
                }

                var threadconns = threadConnection.Value;
                var stacktrace  = new StackTrace(1, true);

                if (threadConnection.Value.Count != 0)
                {
                    Trace.WriteLine($"ERROR: Connection opened twice, expect deadlock");
                    foreach (var kvp in threadconns)
                    {
                        if (kvp.Value.Item1.TryGetTarget(out _))
                        {
                            Trace.WriteLine($"Original connection opened {kvp.Value.Item2.ToString()}");
                        }
                        else
                        {
                            Trace.WriteLine($"Leaked original connection opened {kvp.Value.Item2.ToString()}");
                        }
                    }
                    Trace.WriteLine($"New connection opened {stacktrace.ToString()}");

                    if (Debugger.IsAttached)
                    {
                        Debugger.Break();
                    }
                }

                threadconns[this.ConnectionGuid] = new Tuple <WeakReference <SQLExtConnection>, StackTrace>(new WeakReference <SQLExtConnection>(this, false), stacktrace);

                schemaLock.EnterReadLock();
                locktaken = true;

                // System.Threading.Monitor.Enter(monitor);
                DBFile     = dbfile;
                connection = DbFactory.CreateConnection();

                // Use the database selected by maindb as the 'main' database
                connection.ConnectionString = "Data Source=" + DBFile.Replace("\\", "\\\\") + ";Pooling=true;";

                if (utctimeindicator)   // indicate treat dates as UTC.
                {
                    connection.ConnectionString += "DateTimeKind=Utc;";
                }

                if (mode == AccessMode.Reader)
                {
                    connection.ConnectionString += "Read Only=True;";
                }

                // System.Diagnostics.Debug.WriteLine("Created connection " + connection.ConnectionString);

                transactionLock = new SQLExtTransactionLock <TConn>();
                connection.Open();
            }
            catch
            {
                if (transactionLock != null)
                {
                    transactionLock.Dispose();
                }

                if (locktaken)
                {
                    schemaLock.ExitReadLock();
                }
                throw;
            }
        }
Exemplo n.º 11
0
        public void OpenWriter()
        {
            if (owningThread != Thread.CurrentThread)
            {
                throw new InvalidOperationException("Transaction lock passed between threads");
            }

            if (rwlock.IsReadLockHeld)
            {
                throw new InvalidOperationException("Writer found RW Lock held ");
            }

            if (!isWriter)
            {
                try
                {
                    if (!rwlock.IsUpgradeableReadLockHeld)
                    {
                        bool warned = false;

                        while (!rwlock.TryEnterUpgradeableReadLock(1000))
                        {
                            SQLExtTransactionLock <TConn> lockowner = writeLockOwner;
                            if (lockowner != null)
                            {
                                warned = true;
                                Trace.WriteLine($"{Environment.TickCount % 10000} Thread {Thread.CurrentThread.Name} waiting for thread {lockowner.owningThread.Name} to finish writer");
                                DebugLongRunningOperation(lockowner);
                            }
                        }

                        if (warned)
                        {
                            Trace.WriteLine($"{Environment.TickCount % 10000} Thread {Thread.CurrentThread.Name} Released for write");
                        }

                        isWriter       = true;
                        writeLockOwner = this;
                    }

                    while (!rwlock.TryEnterWriteLock(1000))
                    {
                        Trace.WriteLine($"{Environment.TickCount % 10000}Thread {Thread.CurrentThread.Name} waiting for readers to finish");
                    }
                }
                catch
                {
                    if (isWriter)
                    {
                        if (rwlock.IsWriteLockHeld)
                        {
                            rwlock.ExitWriteLock();
                        }

                        if (rwlock.IsUpgradeableReadLockHeld)
                        {
                            rwlock.ExitUpgradeableReadLock();
                        }
                    }
                }
            }
        }