📄 genericlanguageconnectioncontext.java
字号:
{ return lockEscalationThreshold; } /* The methods that follow are for consistency checking purposes */ public int getCacheSize() { if (statementCache != null) return statementCache.getNumberInUse(); else return 0; } /** * Add the activation to those known about by this connection. */ public void addActivation(Activation a) { acts.addElement(a); if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON("memoryLeakTrace")) { if (acts.size() > 20) System.out.println("memoryLeakTrace:GenericLanguageContext:activations " + acts.size()); } } } /** * @see LanguageConnectionContext#checkIfAnyDeclaredGlobalTempTablesForThisConnection */ public boolean checkIfAnyDeclaredGlobalTempTablesForThisConnection() { return (allDeclaredGlobalTempTables == null ? false : true); } /** * @see LanguageConnectionContext#addDeclaredGlobalTempTable */ public void addDeclaredGlobalTempTable(TableDescriptor td) throws StandardException { if (findDeclaredGlobalTempTable(td.getName()) != null) //if table already declared, throw an exception { throw StandardException.newException( SQLState.LANG_OBJECT_ALREADY_EXISTS_IN_OBJECT, "Declared global temporary table", td.getName(), "Schema", SchemaDescriptor.STD_DECLARED_GLOBAL_TEMPORARY_TABLES_SCHEMA_NAME); } //save all the information about temp table in this special class TempTableInfo tempTableInfo = new TempTableInfo(td, currentSavepointLevel); if (allDeclaredGlobalTempTables == null) allDeclaredGlobalTempTables = new ArrayList(); allDeclaredGlobalTempTables.add(tempTableInfo); } /** * @see LanguageConnectionContext#dropDeclaredGlobalTempTable */ public boolean dropDeclaredGlobalTempTable(String tableName) { TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName); if (tempTableInfo != null) { if (SanityManager.DEBUG) if (tempTableInfo.getDeclaredInSavepointLevel() > currentSavepointLevel) SanityManager.THROWASSERT("declared in savepoint level can not be higher than the current savepoint level"); //following checks if the table was declared in the current unit of work. if (tempTableInfo.getDeclaredInSavepointLevel() == currentSavepointLevel) { //since the table was declared in this unit of work, //the drop table method should remove it from the valid list of temp table for this unit of work allDeclaredGlobalTempTables.remove(allDeclaredGlobalTempTables.indexOf(tempTableInfo)); if (allDeclaredGlobalTempTables.size() == 0) allDeclaredGlobalTempTables = null; } else { //since the table was not declared in this unit of work, the drop table method will just mark the table as dropped //in the current unit of work. This information will be used at rollback time. tempTableInfo.setDroppedInSavepointLevel(currentSavepointLevel); } return true; } else return false; } /** * After a release of a savepoint, we need to go through our temp tables list. If there are tables with their declare or drop * or modified in savepoint levels set to savepoint levels higher than the current savepoint level, then we should change them * to the current savepoint level */ private void tempTablesReleaseSavepointLevels() { //unlike rollback, here we check for dropped in / declared in / modified in savepoint levels > current savepoint level only. //This is because the temp tables with their savepoint levels same as currentSavepointLevel have correct value assigned to them and //do not need to be changed and hence no need to check for >= for (int i = 0; i < allDeclaredGlobalTempTables.size(); i++) { TempTableInfo tempTableInfo = (TempTableInfo)allDeclaredGlobalTempTables.get(i); if (tempTableInfo.getDroppedInSavepointLevel() > currentSavepointLevel) tempTableInfo.setDroppedInSavepointLevel(currentSavepointLevel); if (tempTableInfo.getDeclaredInSavepointLevel() > currentSavepointLevel) tempTableInfo.setDeclaredInSavepointLevel(currentSavepointLevel); if (tempTableInfo.getModifiedInSavepointLevel() > currentSavepointLevel) tempTableInfo.setModifiedInSavepointLevel(currentSavepointLevel); } } /** * do the necessary work at commit time for temporary tables * 1)If a temporary table was marked as dropped in this transaction, then remove it from the list of temp tables for this connection * 2)If a temporary table was not dropped in this transaction, then mark it's declared savepoint level and modified savepoint level as -1 */ private void tempTablesAndCommit() { for (int i = allDeclaredGlobalTempTables.size()-1; i >= 0; i--) { TempTableInfo tempTableInfo = (TempTableInfo)allDeclaredGlobalTempTables.get(i); if (tempTableInfo.getDroppedInSavepointLevel() != -1) { //this means table was dropped in this unit of work and hence should be removed from valid list of temp tables allDeclaredGlobalTempTables.remove(i); } else //this table was not dropped in this unit of work, hence set its declaredInSavepointLevel as -1 and also mark it as not modified { tempTableInfo.setDeclaredInSavepointLevel(-1); tempTableInfo.setModifiedInSavepointLevel(-1); } } } /** Reset the connection before it is returned (indirectly) by a PooledConnection object. See EmbeddedConnection. */ public void resetFromPool() throws StandardException { // Reset IDENTITY_VAL_LOCAL identityNotNull = false; // drop all temp tables. dropAllDeclaredGlobalTempTables(); } /** * Drop all the declared global temporary tables associated with this connection. This gets called * when a getConnection() is done on a PooledConnection. This will ensure all the temporary tables * declared on earlier connection handle associated with this physical database connection are dropped * before a new connection handle is issued on that same physical database connection. */ private void dropAllDeclaredGlobalTempTables() throws StandardException { if (allDeclaredGlobalTempTables == null) return; DependencyManager dm = getDataDictionary().getDependencyManager(); StandardException topLevelStandardException = null; //collect all the exceptions we might receive while dropping the temporary tables and throw them as one chained exception at the end. for (int i = 0; i < allDeclaredGlobalTempTables.size(); i++) { try { TempTableInfo tempTableInfo = (TempTableInfo)allDeclaredGlobalTempTables.get(i); TableDescriptor td = tempTableInfo.getTableDescriptor(); //the following 2 lines of code has been copied from DropTableConstantAction. If there are any changes made there in future, //we should check if they need to be made here too. dm.invalidateFor(td, DependencyManager.DROP_TABLE, this); tran.dropConglomerate(td.getHeapConglomerateId()); } catch (StandardException e) { e.setNestedException(topLevelStandardException); topLevelStandardException = e; } } allDeclaredGlobalTempTables = null; try { internalCommit(true); } catch (StandardException e) { e.setNestedException(topLevelStandardException); topLevelStandardException = e; } if (topLevelStandardException != null) throw topLevelStandardException; } //do the necessary work at rollback time for temporary tables /** * do the necessary work at rollback time for temporary tables * 1)If a temp table was declared in the UOW, then drop it and remove it from list of temporary tables. * 2)If a temp table was declared and dropped in the UOW, then remove it from list of temporary tables. * 3)If an existing temp table was dropped in the UOW, then recreate it with no data. * 4)If an existing temp table was modified in the UOW, then get rid of all the rows from the table. */ private void tempTablesAndRollback() throws StandardException { for (int i = allDeclaredGlobalTempTables.size()-1; i >= 0; i--) { TempTableInfo tempTableInfo = (TempTableInfo)allDeclaredGlobalTempTables.get(i); if (tempTableInfo.getDeclaredInSavepointLevel() >= currentSavepointLevel) { if (tempTableInfo.getDroppedInSavepointLevel() == -1) { //the table was declared but not dropped in the unit of work getting rolled back and hence we will remove //it from valid list of temporary tables and drop the conglomerate associated with it TableDescriptor td = tempTableInfo.getTableDescriptor(); tran.dropConglomerate(td.getHeapConglomerateId()); //remove the conglomerate created for this temp table allDeclaredGlobalTempTables.remove(i); //remove it from the list of temp tables } else if (tempTableInfo.getDroppedInSavepointLevel() >= currentSavepointLevel) { //the table was declared and dropped in the unit of work getting rolled back allDeclaredGlobalTempTables.remove(i); } } else if (tempTableInfo.getDroppedInSavepointLevel() >= currentSavepointLevel) //this means the table was declared in an earlier savepoint unit / transaction and then dropped in current UOW { //restore the old definition of temp table because drop is being rolledback TableDescriptor td = tempTableInfo.getTableDescriptor(); td = cleanupTempTableOnCommitOrRollback(td, false); //In order to store the old conglomerate information for the temp table, we need to replace the //existing table descriptor with the old table descriptor which has the old conglomerate information tempTableInfo.setTableDescriptor(td); tempTableInfo.setDroppedInSavepointLevel(-1); //following will mark the table as not modified. This is because the table data has been deleted as part of the current rollback tempTableInfo.setModifiedInSavepointLevel(-1); allDeclaredGlobalTempTables.set(i, tempTableInfo); } else if (tempTableInfo.getModifiedInSavepointLevel() >= currentSavepointLevel) //this means the table was declared in an earlier savepoint unit / transaction and modified in current UOW { //following will mark the table as not modified. This is because the table data will be deleted as part of the current rollback tempTableInfo.setModifiedInSavepointLevel(-1); TableDescriptor td = tempTableInfo.getTableDescriptor(); getDataDictionary().getDependencyManager().invalidateFor(td, DependencyManager.DROP_TABLE, this); cleanupTempTableOnCommitOrRollback(td, true); } // there is no else here because there is no special processing required for temp tables declares in earlier work of unit/transaction and not modified } if (allDeclaredGlobalTempTables.size() == 0) allDeclaredGlobalTempTables = null; } /** * This is called at the commit time for temporary tables with ON COMMIT DELETE ROWS * If a temp table with ON COMMIT DELETE ROWS doesn't have any held cursor open on them, we delete the data from * them by dropping the conglomerate and recreating the conglomerate. In order to store the new conglomerate * information for the temp table, we need to replace the existing table descriptor with the new table descriptor * which has the new conglomerate information * @param String tableName Temporary table name whose table descriptor is getting changed * @param TableDescriptor td New table descriptor for the temporary table */ private void replaceDeclaredGlobalTempTable(String tableName, TableDescriptor td) { TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName); tempTableInfo.setDroppedInSavepointLevel(-1); tempTableInfo.setDeclaredInSavepointLevel(-1); tempTableInfo.setTableDescriptor(td); allDeclaredGlobalTempTables.set(allDeclaredGlobalTempTables.indexOf(tempTableInfo), tempTableInfo); } /** * @see LanguageConnectionContext#getTableDescriptorForDeclaredGlobalTempTable */ public TableDescriptor getTableDescriptorForDeclaredGlobalTempTable(String tableName) { TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName); if (tempTableInfo == null) return null; else return tempTableInfo.getTableDescriptor(); } /** * Find the declared global temporary table in the list of temporary tables known by this connection. * @param String tableName look for this table name in the saved list * @return data structure defining the temporary table if found. Else, return null * */ private TempTableInfo findDeclaredGlobalTempTable(String tableName) { if (allDeclaredGlobalTempTables == null) return null; for (int i = 0; i < allDeclaredGlobalTempTables.size(); i++) { if (((TempTableInfo)allDeclaredGlobalTempTables.get(i)).matches(tableName)) return (TempTableInfo)allDeclaredGlobalTempTables.get(i); } return null; } /** * @see LanguageConnectionContext#markTempTableAsModifiedInUnitOfWork */ public void markTempTableAsModifiedInUnitOfWork(String tableName) { TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName); tempTableInfo.setModifiedInSavepointLevel(currentSavepointLevel); } /** Return a Statement object to compile a Statement. The schema setting fo the returned statement are that of this connection. */ public PreparedStatement prepareInternalStatement(String sqlText) throws StandardException { return connFactory.getStatement(sd, sqlText).prepare(this); } public PreparedStatement prepareInternalStatement(SchemaDescriptor compilationSchema, String sqlText) throws StandardException { return connFactory.getStatement(compilationSchema, sqlText).prepare(this); } /** * Remove the activation to those known about by this connection. * */ public void removeActivation(Activation a) { if (SanityManager.DEBUG) { SanityManager.ASSERT(a.isClosed(), "Activation is not closed"); } acts.removeElement(a); int capacity = acts.capacity(); if (capacity > 20 && (capacity > 2 * acts.size())) { acts.trimToSize(); } } /** * Return the number of activations known for this connection. * Note that some of these activations may not be in use * (when a prepared statement is finalized, its activations * are marked as unused and later closed and removed on * the next commit/rollback). */ public int getActivationCount() { return acts.size(); } /** * See if a given cursor is available for use. * if so return its activation. Returns null if not found. * For use in execution. * * @return the activation for the given cursor, null * if none was found. */ public CursorActivation lookupCursorActivation(String cursorName) { int size = acts.size(); if (size > 0) { for (int i = 0; i < size; i++) { Activation a = (Activation) acts.elementAt(i); if (!a.isInUse()) { continue; } String executingCursorName = a.getCursorName(); if (cursorName.equals(executingCursorName)) { ResultSet rs = a.getResultSet(); if (rs == null) continue; // if the result set is closed, the the cursor doesn't exist if (rs.isClosed()) { continue; } return (CursorActivation)a; } } } return null; } /** * This method will remove a statement from the statement cache. * It will be called, for example, if there is an exception preparing * the statement. * * @param statement Statement to remove * @exception StandardException thrown if lookup goes wrong. */ public void removeStatement(Statement statement) throws StandardException { if (statementCache == null) return; Cacheable cachedItem = statementCache.findCached(statement); if (cachedItem != null) statementCache.remove(cachedItem); } /** * See if a given statement has already been compiled for this user, and * if so use its prepared statement. Returns null if not found. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -