// 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); }
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}"); } } } }
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; }
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); } } } }
public SQLiteCommandED(DbCommand cmd, SQLiteConnectionED conn, SQLiteTxnLockED<TConn> txnlock, DbTransaction txn = null) { _connection = conn; _txnlock = txnlock; InnerCommand = cmd; if (txn != null) { SetTransaction(txn); } }
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; } }
private static void DebugLongRunningOperation(object state) { WeakReference weakref = state as WeakReference; if (weakref != null) { SQLiteTxnLockED<TConn> txnlock = weakref.Target as SQLiteTxnLockED<TConn>; DebugLongRunningOperation(txnlock); } }
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(); } } } } }
public SQLiteTransactionED(DbTransaction txn, SQLiteTxnLockED<TConn> txnlock) { _transactionLock = txnlock; InnerTransaction = txn; }