/// <summary> /// Releases a transaction to the pool. /// If the transaction is poolable, it is released and put back into the pool, otherwise it is removed. /// Throws an <see cref="InvalidTransactionReleaseException"/> if the transaction is not releasable. /// </summary> /// <exception cref="InvalidTransactionReleaseException">Occurs if the transaction is not releasable.</exception> /// <param name="trans">Transaction to be released.</param> public virtual void ReleaseTransaction(IDbTransaction trans) { if (trans == null) { return; } TransactionInfo transInfo = (TransactionInfo)TransactionPool[trans]; if (transInfo != null) { if (!transInfo.IsReleasable) { throw (new InvalidTransactionReleaseException("Cannot release a transaction that was created with \"GetCommitableTransaction\". Use commit or rollback")); } #if DEBUG_DBCONNECTIONPOOLING OSTrace.Info("DBConnectionPooling[TID=" + transInfo.Transaction.GetHashCode() + "] - returned to pool"); OSTrace.Error(new StackTrace().ToString()); #endif if (transInfo.IsPoolable) { transInfo.Release(); } else { TransactionPool.Remove(trans); } } else { try { if (RequestTransactionInfo != null && trans == RequestTransactionInfo.Transaction) { //when releasing the request transaction make sure the connection is ok if (trans.Connection != null && trans.Connection.State != ConnectionState.Open) { LogException(new InvalidTransactionException("Request transaction not open on release."), new StackTrace(), "Request Transaction discarded due to connection not being in a correct state."); //clear and try to dispose connection lock (this) { RequestTransactionInfo = null; } trans.Connection.Dispose(); } else { RequestTransactionInfo.MarkChange(); } } } catch { //this is a best effort } } }
/// <summary> /// Rolls back all Request transactions. /// </summary> public virtual void RollbackAllTransactions() { if (RequestTransactionInfo != null) { SafeEndTransaction(RequestTransactionInfo, false, /*toFreeResources*/ false); } if (RequestTransactionInfo != null && (RequestTransactionInfo.Connection == null || RequestTransactionInfo.Transaction == null || RequestTransactionInfo.Transaction.Connection == null)) { RequestTransactionInfo.ReturnConnectionToPool(); RequestTransactionInfo = null; } if (RequestTransactionInfo == null) { GetRequestTransaction(); // Set a new request transaction } }
protected override void EndTransaction(TransactionInfo transInfo, bool commit, bool toFreeResources) { //Keep the request transaction open if possible if (!toFreeResources && RequestTransactionInfo != null && RequestTransactionInfo.Equals(transInfo)) { IDbCommand cmd = ExecutionService.CreateCommand(transInfo.Transaction, commit ? "COMMIT" : "ROLLBACK"); try { ExecutionService.ExecuteNonQuery(cmd); } catch (DbException e) { ExecutionService.OnExecuteException(e, cmd, null, transInfo.Connection, transInfo.Transaction, this); throw; } } else { base.EndTransaction(transInfo, commit, toFreeResources); } }
/// <summary> /// Returns a transaction to be used during a web request. /// This transaction is only committed or rolled back by invoking <see cref="FreeupResources"/>. /// </summary> /// <returns>A transaction to be used in the applications.</returns> public virtual IDbTransaction GetRequestTransaction() { lock (this) { if (RequestTransactionInfo == null) { RequestTransactionInfo = BuildTransactionInfo(); } //must discard it and make a new one if the connection is null #52135 if (RequestTransactionInfo.Transaction.Connection == null || RequestTransactionInfo.Transaction.Connection.State == ConnectionState.Closed) { if (RequestTransactionInfo.Transaction.Connection != null) { RequestTransactionInfo.ReturnConnectionToPool(); } RequestTransactionInfo = null; while (RequestTransactionInfo == null) { RequestTransactionInfo = BuildTransactionInfo(); if (RequestTransactionInfo.Transaction.Connection == null || RequestTransactionInfo.Transaction.Connection.State == ConnectionState.Closed) { if (RequestTransactionInfo.Transaction.Connection != null) { RequestTransactionInfo.ReturnConnectionToPool(); } // only log error in the second try LogException(new InvalidTransactionException("Connection in transaction is null."), new StackTrace(), "Releasing connection pools and retrying"); RequestTransactionInfo = null; // retry TransactionService.ReleasePooledConnections("Connection in transaction is null."); Thread.Sleep(TransactionServiceConstants.RETRY_CONNECTION_TIME); } } } RequestTransactionInfo.MarkChange(); return(RequestTransactionInfo.Transaction); } }
/// <summary> /// Rolls back all Request transactions. /// </summary> public virtual void RollbackAllTransactions() { CloseConnectionTransactionException closeConnectionException = null; if (RequestTransactionInfo != null) { SafeEndTransaction(RequestTransactionInfo, false, /*toFreeResources*/ false, out closeConnectionException); } if (RequestTransactionInfo != null && (RequestTransactionInfo.Connection == null || RequestTransactionInfo.Transaction == null || RequestTransactionInfo.Transaction.Connection == null)) { RequestTransactionInfo.ReturnConnectionToPool(); RequestTransactionInfo = null; } if (CheckConnectionCloseException(closeConnectionException)) { throw closeConnectionException; } if (RequestTransactionInfo == null) { GetRequestTransaction(); // Set a new request transaction } }