📄 genericlanguageconnectioncontext.java
字号:
public void userRollback() throws StandardException { doRollback(false /* non-xa */, true); } /** Same as userRollback() except rolls back a distrubuted transaction. @exception StandardException thrown if something goes wrong */ public void xaRollback() throws StandardException { doRollback(true /* xa */, true); } /** * When a rollback happens, the language connection context * will close all open activations and invalidate * their prepared statements. Then the language will abort the * Store transaction. * <p> * The invalidated statements can revalidate themselves without * a full recompile if they verify their dependencies' providers still * exist unchanged. REVISIT when invalidation types are created. * <p> * REVISIT: this may need additional alterations when * RELEASE SAVEPOINT/ROLLBACK TO SAVEPOINT show up. * <p> * Also, tell the data dictionary that the transaction is finished, * if necessary (that is, if the data dictionary was put into * DDL mode in this transaction. * * @param xa true if this is an xa rollback * @param requestedByUser true if requested by user * * @exception StandardException thrown on failure */ private void doRollback(boolean xa, boolean requestedByUser) throws StandardException { StatementContext statementContext = getStatementContext(); if (requestedByUser && (statementContext != null) && statementContext.inUse() && statementContext.isAtomic()) { throw StandardException.newException(SQLState.LANG_NO_ROLLBACK_IN_NESTED_CONNECTION); } // Log rollback to error log, if appropriate if (logStatementText) { if (istream == null) { istream = Monitor.getStream(); } String xactId = tran.getTransactionIdString(); istream.printlnWithHeader(LanguageConnectionContext.xidStr + xactId + "), " + LanguageConnectionContext.lccStr + instanceNumber + "), " + LanguageConnectionContext.dbnameStr + dbname + "), " + LanguageConnectionContext.dbnameStr + dbname + "), " + LanguageConnectionContext.drdaStr + drdaID + "), Rolling back"); } resetActivations(true); currentSavepointLevel = 0; //reset the current savepoint level for the connection to 0 at the beginning of rollback work for temp tables if (allDeclaredGlobalTempTables != null) tempTablesAndRollback(); finishDDTransaction(); // now rollback the Store transaction TransactionController tc = getTransactionExecute(); if (tc != null) { if (xa) ((XATransactionController)tc).xa_rollback(); else tc.abort(); // reset the savepoints to the new // location, since any outer nesting // levels expet there to be a savepoint resetSavepoints(statementContext); } } /* ** Reset all statement savepoints. */ private void resetSavepoints(StatementContext statementContext) throws StandardException { if (statementContext == null) return; ContextManager cm = getContextManager(); Stack stack = new Stack(); // build up a stack with all the statement // contexts. do { stack.push(statementContext); statementContext.popMe(); } while ((statementContext = ((StatementContext)cm.getContext(org.apache.derby.iapi.reference.ContextId.LANG_STATEMENT))) != null); while (!stack.empty()) { statementContext = ((StatementContext)stack.pop()); // reset the savepoints to the new spot statementContext.resetSavePoint(); // replace the contexts that we removed above statementContext.pushMe(); } } /** * Let the context deal with a rollback to savepoint * * @param savepointName Name of the savepoint that needs to be rolled back * @param refreshStyle boolean indicating whether or not the controller should close * open conglomerates and scans. Also used to determine if language should close * open activations. * @param kindOfSavepoint A NULL value means it is an internal savepoint (ie not a user defined savepoint) * Non NULL value means it is a user defined savepoint which can be a SQL savepoint or a JDBC savepoint * A String value for kindOfSavepoint would mean it is SQL savepoint * A JDBC Savepoint object value for kindOfSavepoint would mean it is JDBC savepoint * * @exception StandardException thrown if something goes wrong */ public void internalRollbackToSavepoint( String savepointName, boolean refreshStyle, Object kindOfSavepoint ) throws StandardException { // now rollback the Store transaction to the savepoint TransactionController tc = getTransactionExecute(); if (tc != null) { boolean closeConglomerates; if ( refreshStyle ) { closeConglomerates = true; // bug 5145 - don't forget to close the activations while rolling // back to a savepoint resetActivations(true); } else { closeConglomerates = false; } currentSavepointLevel = tc.rollbackToSavePoint( savepointName, closeConglomerates, kindOfSavepoint ); } if (tc != null && refreshStyle && allDeclaredGlobalTempTables != null) tempTablesAndRollback(); } /** Let the context deal with a release of a savepoint @param savepointName Name of the savepoint that needs to be released @param kindOfSavepoint A NULL value means it is an internal savepoint (ie not a user defined savepoint) Non NULL value means it is a user defined savepoint which can be a SQL savepoint or a JDBC savepoint A String value for kindOfSavepoint would mean it is SQL savepoint A JDBC Savepoint object value for kindOfSavepoint would mean it is JDBC savepoint @exception StandardException thrown if something goes wrong */ public void releaseSavePoint( String savepointName, Object kindOfSavepoint ) throws StandardException { TransactionController tc = getTransactionExecute(); if (tc != null) { currentSavepointLevel = tc.releaseSavePoint( savepointName, kindOfSavepoint ); //after a release of a savepoint, we need to go through our temp tables list. if (allDeclaredGlobalTempTables != null) tempTablesReleaseSavepointLevels(); } } /** Sets a savepoint. Causes the Store to set a savepoint. @param savepointName name of savepoint @param kindOfSavepoint A NULL value means it is an internal savepoint (ie not a user defined savepoint) Non NULL value means it is a user defined savepoint which can be a SQL savepoint or a JDBC savepoint A String value for kindOfSavepoint would mean it is SQL savepoint A JDBC Savepoint object value for kindOfSavepoint would mean it is JDBC savepoint @exception StandardException thrown if something goes wrong */ public void languageSetSavePoint( String savepointName, Object kindOfSavepoint ) throws StandardException { TransactionController tc = getTransactionExecute(); if (tc != null) { currentSavepointLevel = tc.setSavePoint( savepointName, kindOfSavepoint ); } } /** * Return true if any transaction is blocked, even if not by this one * */ public boolean anyoneBlocked() { return getTransactionExecute().anyoneBlocked(); } /** Sets the transaction controller to use with this language connection context. @param tran the transaction to use with this language connection context */ public void setTransaction( TransactionController tran ) { this.tran = tran; } /** * Start a Nested User Transaction (NUT) with the store. If a NUT is * already active simply increment a counter, queryNestingDepth, to keep * track of how many times we have tried to start a NUT. */ public void beginNestedTransaction(boolean readOnly) throws StandardException { if (childTransaction == null) childTransaction = tran.startNestedUserTransaction(readOnly); queryNestingDepth++; return; } public void commitNestedTransaction() throws StandardException { if (--queryNestingDepth == 0) { childTransaction.commit(); childTransaction.destroy(); childTransaction = null; return; } } /** * Get the transaction controller to use at compile time with this language * connection context. If a NUT is active then return NUT else return parent * transaction. */ public TransactionController getTransactionCompile() { return (childTransaction != null) ? childTransaction : tran; } public TransactionController getTransactionExecute() { return tran; } /** Get the data value factory to use with this language connection context. */ public DataValueFactory getDataValueFactory() { return dataFactory; } /** Get the language factory to use with this language connection context. */ public LanguageFactory getLanguageFactory() { return langFactory; } public OptimizerFactory getOptimizerFactory() { return of; } /** Get the language connection factory to use with this language connection context. */ public LanguageConnectionFactory getLanguageConnectionFactory() { return connFactory; } /** * check if there are any activations that reference this temporary table * @param String tableName look for any activations referencing this table name * @return boolean false if found no activations */ private boolean checkIfAnyActivationHasHoldCursor(String tableName) throws StandardException { for (int i = acts.size() - 1; i >= 0; i--) { Activation a = (Activation) acts.elementAt(i); if (a.checkIfThisActivationHasHoldCursor(tableName)) return true; } return false; } /** * Verify that there are no activations with open held result sets. * * @return boolean Found no open (held) resultsets. * * @exception StandardException thrown on failure */ /* This gets used in case of hold cursors. If there are any hold cursors open * then user can't change the isolation level without closing them. At the * execution time, set transaction isolation level calls this method before * changing the isolation level. */ public boolean verifyAllHeldResultSetsAreClosed() throws StandardException { boolean seenOpenResultSets = false; /* For every activation */ for (int i = acts.size() - 1; i >= 0; i--) { Activation a = (Activation) acts.elementAt(i); if (SanityManager.DEBUG) { SanityManager.ASSERT(a instanceof CursorActivation, "a is not a CursorActivation"); } if (!a.isInUse()) { continue; } if (!a.getResultSetHoldability()) { continue; } ResultSet rs = ((CursorActivation) a).getResultSet(); /* is there an open result set? */ if ((rs != null) && !rs.isClosed() && rs.returnsRows()) { seenOpenResultSets = true; break; } } if (!seenOpenResultSets) return(true); // There may be open ResultSet's that are yet to be garbage collected // let's try and force these out rather than throw an error System.gc(); System.runFinalization(); /* For every activation */ for (int i = acts.size() - 1; i >= 0; i--) { Activation a = (Activation) acts.elementAt(i); if (SanityManager.DEBUG) { SanityManager.ASSERT(a instanceof CursorActivation, "a is not a CursorActivation"); } if (!a.isInUse()) { continue; } if (!a.getResultSetHoldability()) { continue; } ResultSet rs = ((CursorActivation) a).getResultSet(); /* is there an open held result set? */ if ((rs != null) && !rs.isClosed() && rs.returnsRows()) { return(false); } } return(true); } /** * Verify that there are no activations with open result sets * on the specified prepared statement. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -