/// <summary> /// Returns transaction object. /// </summary> /// <param name="tablesLockType"> /// <para>SHARED: threads can use listed tables in parallel. Must be used together with tran.SynchronizeTables command, if necessary.</para> /// <para>EXCLUSIVE: if other threads use listed tables for reading or writing, current thread will be in a waiting queue.</para> /// </param> /// <param name="tables"></param> /// <returns>Returns transaction object</returns> public Transaction GetTransaction(eTransactionTablesLockTypes tablesLockType, params string[] tables) { if (!DBisOperable) { throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.DB_IS_NOT_OPERABLE, DBisOperableReason, new Exception()); } //User receives new transaction from the engine return(this._transactionsCoordinator.GetTransaction(1, tablesLockType, tables)); }
/// <summary> /// /// </summary> /// <param name="transactionType">0 = standard transaction, 1 - locked transaction</param> /// <param name="lockType"></param> /// <param name="tables"></param> /// <returns></returns> public Transaction GetTransaction(int transactionType, eTransactionTablesLockTypes lockType, params string[] tables) { //this check is done on upper level //if (!this.DbIsOperatable) // return null; //Transaction must have 2 classes one class is for the user, with appropriate methods, second for technical purposes TransactionDetails, where we store different transaction information //both classes must be bound into one class TransactionUnit TransactionUnit transactionUnit = new TransactionUnit(transactionType, this, lockType, tables); //Checking if the same transaction already exists in the list of Transactions. //It could happen in case of abnormal termination of parallel thread, without disposing of the transaction. //So we delete pending transaction first, then create new one. bool reRun = false; _sync_transactions.EnterReadLock(); try { if (this._transactions.ContainsKey(transactionUnit.TransactionThreadId)) { reRun = true; } } finally { _sync_transactions.ExitReadLock(); } if (reRun) { UnregisterTransaction(transactionUnit.TransactionThreadId); return(GetTransaction(transactionType, lockType, tables)); } //Adding transaction to the list _sync_transactions.EnterWriteLock(); try { this._transactions.Add(transactionUnit.TransactionThreadId, transactionUnit); } catch (System.Exception ex) { throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.TRANSACTION_GETTING_TRANSACTION_FAILED, ex); } finally { _sync_transactions.ExitWriteLock(); } return(transactionUnit.Transaction); }
/// <summary> /// Returns transaction object. /// </summary> /// <param name="tablesLockType"> /// <para>SHARED: threads can use listed tables in parallel. Must be used together with tran.SynchronizeTables command, if necessary.</para> /// <para>EXCLUSIVE: if other threads use listed tables for reading or writing, current thread will be in a waiting queue.</para> /// </param> /// <param name="tables"></param> /// <returns>Returns transaction object</returns> public new Transaction GetTransaction(eTransactionTablesLockTypes tablesLockType, params string[] tables) { Init(); return base.GetTransaction(tablesLockType, tables); }
/// <summary> /// /// </summary> /// <param name="lockType"></param> /// <param name="tables"></param> /// <returns>false if thread grants access, false if thread is in a queue</returns> public bool AddSession(eTransactionTablesLockTypes lockType, string[] tables) { lock (lock_disposed) { if (disposed) { return(true); } } internSession iSession = null; bool ret = true; _sync.EnterWriteLock(); try { foreach (var ses in _acceptedSessions) { if (DbUserTables.TableNamesIntersect(ses.Value.tables.ToList(), tables.ToList())) { if (ses.Value.lockType == eTransactionTablesLockTypes.EXCLUSIVE || lockType == eTransactionTablesLockTypes.EXCLUSIVE) { //Lock ret = false; break; } } } if (!ret) { internSession xSes = null; foreach (var ses in _waitingSessionSequence) { if (ses == Environment.CurrentManagedThreadId) { break; } _waitingSessions.TryGetValue(ses, out xSes); if (DbUserTables.TableNamesIntersect(xSes.tables.ToList(), tables.ToList())) { if (xSes.lockType == eTransactionTablesLockTypes.EXCLUSIVE || lockType == eTransactionTablesLockTypes.EXCLUSIVE) { //Lock ret = false; break; } } } } if (_waitingSessions.TryGetValue(Environment.CurrentManagedThreadId, out iSession)) { //This session was in the waiting list once if (ret) { //We have to take away session from waiting list iSession.gator.Dispose(); iSession.gator = null; _waitingSessions.Remove(Environment.CurrentManagedThreadId); _waitingSessionSequence.Remove(Environment.CurrentManagedThreadId); } else { iSession.gator.CloseGate(); } } else { //Creating new session iSession = new internSession() { lockType = lockType, tables = tables }; if (!ret) { iSession.gator = new DbThreadsGator(false); _waitingSessions.Add(Environment.CurrentManagedThreadId, iSession); _waitingSessionSequence.Add(Environment.CurrentManagedThreadId); } } if (ret) { //Adding into accepted sessions _acceptedSessions.Add(Environment.CurrentManagedThreadId, iSession); } } finally { _sync.ExitWriteLock(); } if (!ret) { //putting gate iSession.gator.PutGateHere(); } return(ret); }
//public TransactionUnit(TransactionsCoordinator transactionsCoordinator) //{ // this._transactionsCoordinator = transactionsCoordinator; // this._transaction = new Transaction(this); //} public TransactionUnit(int transactionType, TransactionsCoordinator transactionsCoordinator, eTransactionTablesLockTypes lockType, params string[] tables) { this._transactionsCoordinator = transactionsCoordinator; this._transaction = new Transaction(transactionType, this, lockType, tables); }
/// <summary> /// /// </summary> /// <param name="transactionType">0 = standard transaction, 1 - locked transaction</param> /// <param name="lockType"></param> /// <param name="tables"></param> /// <returns></returns> public Transaction GetTransaction(int transactionType, eTransactionTablesLockTypes lockType, params string[] tables) { //this check is done on upper level //if (!this.DbIsOperatable) // return null; //Transaction must have 2 classes one class is for the user, with appropriate methods, second for technical purposes TransactionDetails, where we store different transaction information //both classes must be bound into one class TransactionUnit TransactionUnit transactionUnit = new TransactionUnit(transactionType, this, lockType, tables); //Checking if the same transaction already exists in the list of Transactions. //It could happen in case of abnormal termination of parallel thread, without disposing of the transaction. //So we delete pending transaction first, then create new one. bool reRun = false; _sync_transactions.EnterReadLock(); try { if (this._transactions.ContainsKey(transactionUnit.TransactionThreadId)) { reRun = true; } } finally { _sync_transactions.ExitReadLock(); } if (reRun) { UnregisterTransaction(transactionUnit.TransactionThreadId); return GetTransaction(transactionType, lockType, tables); } //Adding transaction to the list _sync_transactions.EnterWriteLock(); try { this._transactions.Add(transactionUnit.TransactionThreadId, transactionUnit); } catch (System.Exception ex) { throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.TRANSACTION_GETTING_TRANSACTION_FAILED, ex); } finally { _sync_transactions.ExitWriteLock(); } return transactionUnit.Transaction; }
/// <summary> /// Returns transaction object. /// </summary> /// <param name="tablesLockType"> /// <para>SHARED: threads can use listed tables in parallel. Must be used together with tran.SynchronizeTables command, if necessary.</para> /// <para>EXCLUSIVE: if other threads use listed tables for reading or writing, current thread will be in a waiting queue.</para> /// </param> /// <param name="tables"></param> /// <returns>Returns transaction object</returns> public Transaction GetTransaction(eTransactionTablesLockTypes tablesLockType, params string[] tables) { if (!DBisOperable) throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.DB_IS_NOT_OPERABLE, DBisOperableReason, new Exception()); //User receives new transaction from the engine return this._transactionsCoordinator.GetTransaction(1, tablesLockType, tables); }
/// <summary> /// Returns transaction object. /// </summary> /// <param name="tablesLockType"> /// <para>SHARED: threads can use listed tables in parallel. Must be used together with tran.SynchronizeTables command, if necessary.</para> /// <para>EXCLUSIVE: if other threads use listed tables for reading or writing, current thread will be in a waiting queue.</para> /// </param> /// <param name="tables"></param> /// <returns>Returns transaction object</returns> public new Transaction GetTransaction(eTransactionTablesLockTypes tablesLockType, params string[] tables) { Init(); return(base.GetTransaction(tablesLockType, tables)); }
/// <summary> /// /// </summary> /// <param name="lockType"></param> /// <param name="tables"></param> /// <returns>false if thread grants access, false if thread is in a queue</returns> public bool AddSession(eTransactionTablesLockTypes lockType, string[] tables) { lock (lock_disposed) { if (disposed) return true; } internSession iSession = null; bool ret = true; _sync.EnterWriteLock(); try { foreach (var ses in _acceptedSessions) { if (DbUserTables.TableNamesIntersect(ses.Value.tables.ToList(), tables.ToList())) { if (ses.Value.lockType == eTransactionTablesLockTypes.EXCLUSIVE || lockType == eTransactionTablesLockTypes.EXCLUSIVE) { //Lock ret = false; break; } } } if (!ret) { internSession xSes = null; foreach (var ses in _waitingSessionSequence) { if (ses == System.Threading.Thread.CurrentThread.ManagedThreadId) break; _waitingSessions.TryGetValue(ses, out xSes); if (DbUserTables.TableNamesIntersect(xSes.tables.ToList(), tables.ToList())) { if (xSes.lockType == eTransactionTablesLockTypes.EXCLUSIVE || lockType == eTransactionTablesLockTypes.EXCLUSIVE) { //Lock ret = false; break; } } } } if (_waitingSessions.TryGetValue(System.Threading.Thread.CurrentThread.ManagedThreadId, out iSession)) { //This session was in the waiting list once if (ret) { //We have to take away session from waiting list iSession.gator.Dispose(); iSession.gator = null; _waitingSessions.Remove(System.Threading.Thread.CurrentThread.ManagedThreadId); _waitingSessionSequence.Remove(System.Threading.Thread.CurrentThread.ManagedThreadId); } else { iSession.gator.CloseGate(); } } else { //Creating new session iSession = new internSession() { lockType = lockType, tables = tables }; if (!ret) { iSession.gator = new DbThreadsGator(false); _waitingSessions.Add(System.Threading.Thread.CurrentThread.ManagedThreadId, iSession); _waitingSessionSequence.Add(System.Threading.Thread.CurrentThread.ManagedThreadId); } } if (ret) { //Adding into accepted sessions _acceptedSessions.Add(System.Threading.Thread.CurrentThread.ManagedThreadId, iSession); } } finally { _sync.ExitWriteLock(); } if (!ret) { //putting gate iSession.gator.PutGateHere(); } return ret; }