/// <summary> /// Enter collection reserved lock mode (only 1 collection per time can have this lock) /// </summary> public void EnterReserved(string collectionName) { ENSURE(_transaction.IsReadLockHeld, "Use EnterTransaction() before EnterReserved(name)"); // checks if engine was open in readonly mode if (_readonly) { throw new LiteException(0, "This operation are not support because engine was open in reaodnly mode"); } // if thread are in full reserved, don't try lock if (_reserved.IsWriteLockHeld) { return; } // reserved locker in read lock (if not already reserved in this thread be another snapshot) if (_reserved.IsReadLockHeld == false && _reserved.TryEnterReadLock(_timeout) == false) { throw LiteException.LockTimeout("reserved", collectionName, _timeout); } // get collection locker from dictionary (or create new if doesnt exists) var collection = _collections.GetOrAdd(collectionName, (s) => new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion)); // try enter in reserved lock in collection if (collection.TryEnterUpgradeableReadLock(_timeout) == false) { // if get timeout, release first reserved lock _reserved.ExitReadLock(); throw LiteException.LockTimeout("reserved", collectionName, _timeout); } }
/// <summary> /// Enter collection write lock mode (only 1 collection per time can have this lock) /// </summary> public void EnterLock(string collectionName) { ENSURE(_transaction.IsReadLockHeld || _transaction.IsWriteLockHeld, "Use EnterTransaction() before EnterLock(name)"); // get collection object lock from dictionary (or create new if doesnt exists) var collection = _collections.GetOrAdd(collectionName, (s) => new object()); if (Monitor.TryEnter(collection, _pragmas.Timeout) == false) { throw LiteException.LockTimeout("write", collectionName, _pragmas.Timeout); } }
/// <summary> /// Enter collection in read lock /// </summary> public void EnterRead(string collectionName) { ENSURE(_transaction.IsReadLockHeld || _transaction.IsWriteLockHeld, "Use EnterTransaction() before EnterRead(name)"); // get collection locker from dictionary (or create new if doesnt exists) var collection = _collections.GetOrAdd(collectionName, (s) => new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion)); // try enter in read lock in collection if (collection.TryEnterReadLock(_timeout) == false) { throw LiteException.LockTimeout("read", collectionName, _timeout); } }
/// <summary> /// Enter transaction read lock - should be called just before enter a new transaction /// </summary> public void EnterTransaction() { // if current thread already in exclusive mode, just exit if (_transaction.IsWriteLockHeld) { return; } if (_transaction.TryEnterReadLock(_pragmas.Timeout) == false) { throw LiteException.LockTimeout("transaction", _pragmas.Timeout); } }
/// <summary> /// Enter all database in exclusive lock. Wait for all transactions finish. In exclusive mode no one can enter in new transaction (for read/write) /// If current thread already in exclusive mode, returns false /// </summary> public bool EnterExclusive() { // if current thread already in exclusive mode if (_transaction.IsWriteLockHeld) { return(false); } // wait finish all transactions before enter in reserved mode if (_transaction.TryEnterWriteLock(_pragmas.Timeout) == false) { throw LiteException.LockTimeout("exclusive", _pragmas.Timeout); } return(true); }
/// <summary> /// Enter all database in exclusive lock. Wait for all reader/writers. In exclusive mode no one can read/write any another /// If current thread already in exclusive mode, returns false /// </summary> public bool EnterExclusive() { // if current thread already in exclusive mode if (_transaction.IsWriteLockHeld) { return(false); } // wait finish all transactions before enter in reserved mode if (_transaction.TryEnterWriteLock(_pragmas.Timeout) == false) { throw LiteException.LockTimeout("exclusive", _pragmas.Timeout); } ENSURE(_transaction.RecursiveReadCount == 0, "must have no other transaction here"); return(true); }
/// <summary> /// Enter transaction read lock /// </summary> public void EnterTransaction() { // if current thread are in reserved mode, do not enter in transaction if (_transaction.IsWriteLockHeld) { return; } try { if (_transaction.TryEnterReadLock(_timeout) == false) { throw LiteException.LockTimeout("transaction", _timeout); } } catch (LockRecursionException) { throw LiteException.AlreadyExistsTransaction(); } }
/// <summary> /// Enter all database in reserved lock. Wait for all reader/writers. /// If exclusive = false, new readers can read but no writers can write. If exclusive = true, no new readers/writers /// </summary> public void EnterReserved(bool exclusive) { // checks if engine was open in readonly mode if (_readonly) { throw new LiteException(0, "This operation are not support because engine was open in reaodnly mode"); } // wait finish all transactions before enter in reserved mode if (_transaction.TryEnterWriteLock(_timeout) == false) { throw LiteException.LockTimeout("reserved", _timeout); } ENSURE(_transaction.RecursiveReadCount == 0, "must have no other transaction here"); try { // reserved locker in write lock if (_reserved.TryEnterWriteLock(_timeout) == false) { // exit transaction write lock _transaction.ExitWriteLock(); throw LiteException.LockTimeout("reserved", _timeout); } } finally { if (exclusive == false) { // exit exclusive and allow new readers _transaction.ExitWriteLock(); } } }