📄 embedconnection.java
字号:
} } if (!isClosed()) setInactive(); } } /** * Tests to see if a Connection is closed. * * @return true if the connection is closed; false if it's still open */ public final boolean isClosed() { if (active) { // I am attached, check the database state if (getTR().isActive()) { return false; } setInactive(); } return true; } /** * A Connection's database is able to provide information * describing its tables, its supported SQL grammar, its stored * procedures, the capabilities of this connection, etc. This * information is made available through a DatabaseMetaData * object. * * @return a DatabaseMetaData object for this Connection * @exception SQLException if a database-access error occurs. */ public DatabaseMetaData getMetaData() throws SQLException { if (isClosed()) throw Util.noCurrentConnection(); if (dbMetadata == null) { // There is a case where dbname can be null. // Replication client of this method does not have a // JDBC connection; therefore dbname is null and this // is expected. // dbMetadata = factory.newEmbedDatabaseMetaData(this, getTR().getUrl()); } return dbMetadata; } /** JDBC 3.0 * Retrieves the current holdability of ResultSet objects created using this * Connection object. * * * @return The holdability, one of ResultSet.HOLD_CURSORS_OVER_COMMIT * or ResultSet.CLOSE_CURSORS_AT_COMMIT * */ public final int getHoldability() { return connectionHoldAbility; } /** JDBC 3.0 * Changes the holdability of ResultSet objects created using this * Connection object to the given holdability. * * * @param holdability A ResultSet holdability constant, one of ResultSet.HOLD_CURSORS_OVER_COMMIT * or ResultSet.CLOSE_CURSORS_AT_COMMIT * */ public final void setHoldability(int holdability) { connectionHoldAbility = holdability; } /** * You can put a connection in read-only mode as a hint to enable * database optimizations. * * <P><B>Note:</B> setReadOnly cannot be called while in the * middle of a transaction. * * @param readOnly true enables read-only mode; false disables * read-only mode. * @exception SQLException if a database-access error occurs. */ public final void setReadOnly(boolean readOnly) throws SQLException { synchronized(getConnectionSynchronization()) { setupContextStack(); try { getLanguageConnection().setReadOnly(readOnly); } catch (StandardException e) { throw handleException(e); } finally { restoreContextStack(); } } } /** * Tests to see if the connection is in read-only mode. * * @return true if connection is read-only * @exception SQLException if a database-access error occurs. */ public final boolean isReadOnly() throws SQLException { return getLanguageConnection().isReadOnly(); } /** * A sub-space of this Connection's database may be selected by setting a * catalog name. If the driver does not support catalogs it will * silently ignore this request. * * @exception SQLException if a database-access error occurs. */ public void setCatalog(String catalog) throws SQLException { // silently ignoring this request like the javadoc said. return; } /** * Return the Connection's current catalog name. * * @return the current catalog name or null * @exception SQLException if a database-access error occurs. */ public String getCatalog() throws SQLException { // we do not have support for Catalog, just return null as // the JDBC specs mentions then. return null; } /** * You can call this method to try to change the transaction * isolation level using one of the TRANSACTION_* values. * * <P><B>Note:</B> setTransactionIsolation causes the current * transaction to commit * * @param level one of the TRANSACTION_* isolation values with the * exception of TRANSACTION_NONE; some databases may not support * other values * @exception SQLException if a database-access error occurs. * @see DatabaseMetaData#supportsTransactionIsolationLevel */ public void setTransactionIsolation(int level) throws SQLException { if (level == getTransactionIsolation()) return; // Convert the isolation level to the internal one int iLevel; switch (level) { case java.sql.Connection.TRANSACTION_READ_UNCOMMITTED: iLevel = ExecutionContext.READ_UNCOMMITTED_ISOLATION_LEVEL; break; case java.sql.Connection.TRANSACTION_READ_COMMITTED: iLevel = ExecutionContext.READ_COMMITTED_ISOLATION_LEVEL; break; case java.sql.Connection.TRANSACTION_REPEATABLE_READ: iLevel = ExecutionContext.REPEATABLE_READ_ISOLATION_LEVEL; break; case java.sql.Connection.TRANSACTION_SERIALIZABLE: iLevel = ExecutionContext.SERIALIZABLE_ISOLATION_LEVEL; break; default: throw newSQLException(SQLState.UNIMPLEMENTED_ISOLATION_LEVEL, new Integer(level)); } synchronized(getConnectionSynchronization()) { setupContextStack(); try { getLanguageConnection().setIsolationLevel(iLevel); } catch (StandardException e) { throw handleException(e); } finally { restoreContextStack(); } } } /** * Get this Connection's current transaction isolation mode. * * @return the current TRANSACTION_* mode value * @exception SQLException if a database-access error occurs. */ public final int getTransactionIsolation() throws SQLException { return ExecutionContext.CS_TO_JDBC_ISOLATION_LEVEL_MAP[getLanguageConnection().getCurrentIsolationLevel()]; } /** * The first warning reported by calls on this Connection is * returned. * * <P><B>Note:</B> Subsequent warnings will be chained to this * SQLWarning. * * @return the first SQLWarning or null * * Synchronization note: Warnings are synchronized * on nesting level */ public final synchronized SQLWarning getWarnings() { return topWarning; } /** * After this call, getWarnings returns null until a new warning is * reported for this Connection. * * Synchronization node: Warnings are synchonized * on nesting level */ public final synchronized void clearWarnings() { topWarning = null; } ///////////////////////////////////////////////////////////////////////// // // JDBC 2.0 - New public methods // ///////////////////////////////////////////////////////////////////////// /** * * Get the type-map object associated with this connection. * By default, the map returned is empty. * JDBC 2.0 - java.util.Map requires JDK 1 * */ public final java.util.Map getTypeMap() { // just return an immuntable empty map return java.util.Collections.EMPTY_MAP; } /** * Install a type-map object as the default type-map for * this connection. * JDBC 2.0 - java.util.Map requires JDK 1 * * @exception SQLException Feature not implemented for now. */ public final void setTypeMap(java.util.Map map) throws SQLException { if( map == null) throw Util.generateCsSQLException(SQLState.INVALID_API_PARAMETER,map,"map", "java.sql.Connection.setTypeMap"); if(!(map.isEmpty())) throw Util.notImplemented(); } ///////////////////////////////////////////////////////////////////////// // // Implementation specific methods // ///////////////////////////////////////////////////////////////////////// /** Add a warning to the current list of warnings, to follow this note from Connection.getWarnings. Note: Subsequent warnings will be chained to this SQLWarning. @see java.sql.Connection#getWarnings */ public final synchronized void addWarning(SQLWarning newWarning) { if (topWarning == null) { topWarning = newWarning; return; } topWarning.setNextWarning(newWarning); } /** * Return the dbname for this connection. * * @return String The dbname for this connection. */ public String getDBName() { if (SanityManager.DEBUG) SanityManager.ASSERT(!isClosed(), "connection is closed"); return getTR().getDBName(); } public final LanguageConnectionContext getLanguageConnection() { if (SanityManager.DEBUG) SanityManager.ASSERT(!isClosed(), "connection is closed"); return getTR().getLcc(); } //EmbedConnection30 overrides this method so it can release the savepoints array if //the exception severity is transaction level public SQLException handleException(Throwable thrownException) throws SQLException { /* ** By default, rollback the connection on if autocommit ** is on. */ return getTR().handleException(thrownException, autoCommit, true // Rollback xact on auto commit ); } /** Handle any type of Exception. <UL> <LI> Inform the contexts of the error <LI> Throw an Util based upon the thrown exception. </UL> REMIND: now that we know all the exceptions from our driver are Utils, would it make sense to shut down the system for unknown SQLExceptions? At present, we do not. Because this is the last stop for exceptions, it will catch anything that occurs in it and try to cleanup before re-throwing them. @param thrownException the exception @param rollbackOnAutoCommit rollback the xact on if autocommit is on, otherwise rollback stmt but leave xact open (and continue to hold on to locks). Most of the time, this will be true, excepting operations on result sets, like getInt(). */ final SQLException handleException(Throwable thrownException, boolean rollbackOnAutoCommit) throws SQLException { return getTR().handleException(thrownException, autoCommit, rollbackOnAutoCommit); } /* This is called from the EmbedConnectionContext to close on errors. We assume all handling of the connectin is dealt with via the context stack, and our only role is to mark ourself as closed. */ /** Close the connection when processing errors, or when closing a nested connection. <p> This only marks it as closed and frees up its resources; any closing of the underlying connection or commit work is assumed to be done elsewhere. Called from EmbedConnectionContext's cleanup routine, and by proxy.close(). */ public final void setInactive() { if (active == false) return; // active = false // tr = null !-> active = false synchronized (getConnectionSynchronization()) { active = false; // tr = null; cleanupOnerror sets inactive but still needs tr to // restore context later dbMetadata = null; } } /** @exception Throwable standard error policy */ protected void finalize() throws Throwable { if (rootConnection == this) { super.finalize(); if (!isClosed()) close(exceptionClose); } } /** * if auto commit is on, remember that we need to commit * the current statement. */ protected void needCommit() { if (!needCommit) needCommit = true; } /** * if a commit is needed, perform it. * * Must have connection synchonization and context set up already. * * @exception SQLException if commit returns error */ protected void commitIfNeeded() throws SQLException { if (autoCommit && needCommit) { try { getTR().commit(); } catch (Throwable t) { throw handleException(t); } needCommit = false; } } /** * If in autocommit, then commit. * * Used to force a commit after a result set closes in autocommit mode. * The needCommit mechanism does not work correctly as there are times * with cursors (like a commit, followed by a next, followed by a close) * where the system does not think it needs a commit but we need to * force the commit on close. It seemed safer to just force a commit * on close rather than count on keeping the needCommit flag correct for * all cursor cases. * * Must have connection synchonization and context set up already. * * @exception SQLException if commit returns error */ protected void commitIfAutoCommit() throws SQLException { if (autoCommit) { try { getTR().commit(); } catch (Throwable t) { throw handleException(t); } needCommit = false; } } final protected Object getConnectionSynchronization() { return rootConnection; } /** Install the context manager for this thread. Check connection status here. @exception SQLException if fails */ protected final void setupContextStack() throws SQLException { /* Track this entry, then throw an exception rather than doing the quiet return. Need the track before the throw because the backtrack is in a finally block. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -