private void SafeEndTransaction(TransactionInfo transInfo, bool commit, bool toFreeResources, out CloseConnectionTransactionException closeConnectionException) { closeConnectionException = null; try { #if DEBUG_DBCONNECTIONPOOLING OSTrace.Error("DBConnectionPooling[TID=" + transInfo.Transaction.GetHashCode() + "] - returned to pool"); OSTrace.Error(new StackTrace().ToString()); #endif EndTransaction(transInfo, commit, toFreeResources); } catch (InvalidOperationException e) { //Do not collect exception in case of invalid operation exception. // End transaction throws this exception if connection is already commited and we don't want to throw that to client #if DEBUG_DBCONNECTIONPOOLING OSTrace.Error("DBConnectionPooling[TID=" + transInfo.Transaction.GetHashCode() + "]"); OSTrace.Error(new StackTrace().ToString()); #endif EventLogger.WriteError(String.Format("Error closing the transaction to the database: {0}\n{1}\n{2}", e.Message, e.StackTrace, new StackTrace(true))); } catch (Exception e) { #if DEBUG_DBCONNECTIONPOOLING OSTrace.Error("DBConnectionPooling[TID=" + transInfo.Transaction.GetHashCode() + "]"); OSTrace.Error(new StackTrace().ToString()); #endif //collect here exception, so it can be bubbled up and thrown if needed closeConnectionException = new CloseConnectionTransactionException("Error closing the transaction to the database", e); EventLogger.WriteError(String.Format("Error closing the transaction to the database: {0}\n{1}\n{2}", e.Message, e.StackTrace, new StackTrace(true))); } }
/// <summary> /// Releases all database resources being used. /// All transactions are committed or rolled back, and connections are returned to the pool. /// This implementation calls the <see cref="EndTransaction"/> method to end the transactions /// and sets the <see cref="RequestTransactionInfo"/> to Null. /// </summary> /// <param name="commit">If True, all transaction are committed. Otherwise, they are rolled back.</param> public virtual void FreeupResources(bool commit) { CloseConnectionTransactionException closeConnectionException = null; lock (TransactionPool.SyncRoot) { // Note: The "new ArrayList" duplicates the values because "endTransaction" deletes them. foreach (TransactionInfo transInfo in TransactionPool.Values.Cast <TransactionInfo>().ToArray()) { SafeEndTransaction(transInfo, commit, /*toFreeResources*/ true, out closeConnectionException); } } lock (this) { if (RequestTransactionInfo != null) { SafeEndTransaction(RequestTransactionInfo, commit, /*toFreeResources*/ true, out closeConnectionException); RequestTransactionInfo = null; } } }
/// <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 } }
private bool CheckConnectionCloseException(CloseConnectionTransactionException closeConnectionException) { return(closeConnectionException != null); }
// add this on machine config to turn it on: <add key="OutSystems.Extensibility.Data.TransactionService.BubbleUpErrorOnCommit" value="true" /> private bool CheckConnectionCloseException(CloseConnectionTransactionException closeConnectionException) { return(closeConnectionException != null && BubbleUpCommitAndRollbackSetting); }