Beispiel #1
0
 public SQLiteDataReaderED(DbCommand cmd, CommandBehavior behaviour, SQLiteTransactionED <TConn> txn = null, SQLiteTxnLockED <TConn> txnlock = null)
 {
     this._command     = cmd;
     this.InnerReader  = cmd.ExecuteReader(behaviour);
     this._transaction = txn;
     this._txnlock     = txnlock;
 }
Beispiel #2
0
        public void OpenReader()
        {
            if (_owningThread != Thread.CurrentThread)
            {
                throw new InvalidOperationException("Transaction lock passed between threads");
            }

            if (!_lock.IsWriteLockHeld)
            {
                if (!_isReader)
                {
                    try
                    {
                        Interlocked.Increment(ref _readsWaiting);
                        while (!_lock.TryEnterReadLock(1000))
                        {
                            SQLiteTxnLockED <TConn> lockowner = _writeLockOwner;
                            if (lockowner != null)
                            {
                                Trace.WriteLine($"Thread {Thread.CurrentThread.Name} waiting for thread {lockowner._owningThread.Name} to finish writer");
                                DebugLongRunningOperation(lockowner);
                            }
                        }

                        _isReader = true;
                    }
                    finally
                    {
                        Interlocked.Decrement(ref _readsWaiting);
                    }
                }
            }
        }
Beispiel #3
0
        private static void DebugLongRunningOperation(SQLiteTxnLockED <TConn> txnlock)
        {
            if (txnlock != null)
            {
                txnlock._isLongRunning = true;

                if (txnlock._commandExecuting)
                {
                    if (txnlock._isLongRunning)
                    {
                        Trace.WriteLine($"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($"The transaction lock has been held for a long time.");

                    if (txnlock._commandText != null)
                    {
                        Trace.WriteLine($"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 (_cn != null)
                {
                    _cn.Close();
                    _cn.Dispose();
                    _cn = null;
                }

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

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

            base.Dispose(disposing);
        }
Beispiel #5
0
 public SQLiteCommandED(DbCommand cmd, SQLiteConnectionED conn, SQLiteTxnLockED <TConn> txnlock, DbTransaction txn = null)
 {
     _connection  = conn;
     _txnlock     = txnlock;
     InnerCommand = cmd;
     if (txn != null)
     {
         SetTransaction(txn);
     }
 }
Beispiel #6
0
        public override void Close()
        {
            InnerReader.Close();

            if (_txnlock != null)
            {
                _txnlock.CloseReader();
                _txnlock = null;
            }
        }
        public SQLiteConnectionED(EDDSqlDbSelection?maindb = null, bool utctimeindicator = false, bool initializing = false, bool shortlived = true)
            : base(initializing)
        {
            bool locktaken = false;

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

                    if (typeof(TConn) == typeof(SQLiteConnectionUser))
                    {
                        SQLiteConnectionUser.Initialize();
                    }
                    else if (typeof(TConn) == typeof(SQLiteConnectionSystem))
                    {
                        SQLiteConnectionSystem.Initialize();
                    }
                }

                _schemaLock.EnterReadLock();
                locktaken = true;

                // System.Threading.Monitor.Enter(monitor);
                //Console.WriteLine("Connection open " + System.Threading.Thread.CurrentThread.Name);
                DBFile = GetSQLiteDBFile(maindb ?? EDDSqlDbSelection.EDDUser);
                _cn    = DbFactory.CreateConnection();

                // Use the database selected by maindb as the 'main' database
                _cn.ConnectionString = "Data Source=" + DBFile + ";Pooling=true;";

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

                _transactionLock = new SQLiteTxnLockED <TConn>();
                _cn.Open();
            }
            catch
            {
                if (_transactionLock != null)
                {
                    _transactionLock.Dispose();
                }

                if (locktaken)
                {
                    _schemaLock.ExitReadLock();
                }
                throw;
            }
        }
Beispiel #8
0
        public void OpenWriter()
        {
            if (_owningThread != Thread.CurrentThread)
            {
                throw new InvalidOperationException("Transaction lock passed between threads");
            }

            if (_lock.IsReadLockHeld)
            {
                throw new InvalidOperationException("Write attempted in read-only connection");
            }

            if (!_isWriter)
            {
                try
                {
                    if (!_lock.IsUpgradeableReadLockHeld)
                    {
                        while (!_lock.TryEnterUpgradeableReadLock(1000))
                        {
                            SQLiteTxnLockED <TConn> lockowner = _writeLockOwner;
                            if (lockowner != null)
                            {
                                Trace.WriteLine($"Thread {Thread.CurrentThread.Name} waiting for thread {lockowner._owningThread.Name} to finish writer");
                                DebugLongRunningOperation(lockowner);
                            }
                        }

                        _isWriter       = true;
                        _writeLockOwner = this;
                    }

                    while (!_lock.TryEnterWriteLock(1000))
                    {
                        Trace.WriteLine($"Thread {Thread.CurrentThread.Name} waiting for readers to finish");
                    }
                }
                catch
                {
                    if (_isWriter)
                    {
                        if (_lock.IsWriteLockHeld)
                        {
                            _lock.ExitWriteLock();
                        }

                        if (_lock.IsUpgradeableReadLockHeld)
                        {
                            _lock.ExitUpgradeableReadLock();
                        }
                    }
                }
            }
        }
Beispiel #9
0
        private static void DebugLongRunningOperation(object state)
        {
            WeakReference weakref = state as WeakReference;

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

                DebugLongRunningOperation(txnlock);
            }
        }
Beispiel #10
0
        public SQLiteConnectionED(EDDSqlDbSelection?maindb = null, bool utctimeindicator = false, bool initializing = false, bool shortlived = true)
            : base(initializing)
        {
            bool locktaken = false;

            try
            {
                _schemaLock.EnterReadLock();
                locktaken = true;

                // System.Threading.Monitor.Enter(monitor);
                //Console.WriteLine("Connection open " + System.Threading.Thread.CurrentThread.Name);
                DBFile = GetSQLiteDBFile(maindb ?? SQLiteDBClass.DefaultMainDatabase);
                _cn    = SQLiteDBClass.CreateCN();

                // Use the database selected by maindb as the 'main' database
                _cn.ConnectionString = "Data Source=" + DBFile + ";Pooling=true;";

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

                _transactionLock = new SQLiteTxnLockED <TConn>();
                _cn.Open();
            }
            catch
            {
                if (_transactionLock != null)
                {
                    _transactionLock.Dispose();
                }

                if (locktaken)
                {
                    _schemaLock.ExitReadLock();
                }
                throw;
            }
        }
 public DbTransaction BeginTransaction()
 {
     // Take the transaction lock before beginning the
     // transaction to avoid a deadlock
     var txnlock = new SQLiteTxnLockED();
     txnlock.Open();
     return new SQLiteTransactionED(_cn.BeginTransaction(), txnlock);
 }
Beispiel #12
0
 public SQLiteTransactionED(DbTransaction txn, SQLiteTxnLockED <TConn> txnlock)
 {
     _transactionLock = txnlock;
     InnerTransaction = txn;
 }
Beispiel #13
0
 public SQLiteDataReaderED(DbCommand cmd, CommandBehavior behaviour, SQLiteTransactionED txn = null, SQLiteTxnLockED txnlock = null)
 {
     this._command = cmd;
     this.InnerReader = cmd.ExecuteReader(behaviour);
     this._transaction = txn;
     this._txnlock = txnlock;
 }
Beispiel #14
0
 protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
 {
     if (this._transaction != null)
     {
         // The transaction should already have the transaction lock
         return new SQLiteDataReaderED(this.InnerCommand, behavior, txn: this._transaction);
     }
     else
     {
         // Take the transaction lock for the duration of this command
         using (var txnlock = new SQLiteTxnLockED())
         {
             txnlock.Open();
             return new SQLiteDataReaderED(this.InnerCommand, behavior, txnlock: txnlock);
         }
     }
 }
Beispiel #15
0
        // disposing: true if Dispose() was called, false
        // if being finalized by the garbage collector
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                // Close the transaction before closing the lock
                if (InnerTransaction != null)
                {
                    InnerTransaction.Dispose();
                    InnerTransaction = null;
                }

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

            base.Dispose(disposing);
        }
Beispiel #16
0
 public SQLiteTransactionED(DbTransaction txn, SQLiteTxnLockED txnlock)
 {
     _transactionLock = txnlock;
     InnerTransaction = txn;
 }
Beispiel #17
0
 public override object ExecuteScalar()
 {
     if (this._transaction != null)
     {
         this._transaction.BeginCommand(this);
         // The transaction should already have the transaction lock
         object result = InnerCommand.ExecuteScalar();
         this._transaction.EndCommand();
         return result;
     }
     else
     {
         // Take the transaction lock for the duration of this command
         using (var txnlock = new SQLiteTxnLockED())
         {
             txnlock.Open();
             txnlock.BeginCommand(this);
             object result = InnerCommand.ExecuteScalar();
             txnlock.EndCommand();
             return result;
         }
     }
 }