genericdatasource.java

来自「这是一个轻便的j2ee的web应用框架,是一个在多个项目中运用的实际框架,采用s」· Java 代码 · 共 950 行 · 第 1/2 页

JAVA
950
字号
    /**
     * The number of connections created by this data source that are
     * currently in use.
     */
    protected int useCount = 0;

    public int getUseCount() {
        return (this.useCount);
    }


    /**
     * The database username for use in establishing a connection.
     */
    protected String user = null;

    public String getUser() {
        return (this.user);
    }

    public void setUser(String user) {
        this.user = user;
        addProperty("user", this.user);
    }


    // ----------------------------------------------------- DataSource Methods


    /**
     * Attempt to establish a database connection.
     *
     * @exception SQLException if a database access error occurs
     */
    public Connection getConnection() throws SQLException {

        int seconds = 0;
        if (log.isInfoEnabled()) {
            log.info("  getConnection()");
        }

        // Validate the opened status of this data source
        if (closed) {
            throw new SQLException("getConnection:  Data source is closed");
        }
        if (driver == null) {
            open();
        }

        while (true) {

            // Have we timed out yet?
            if (log.isInfoEnabled()) {
                log.info("   Check for timeout, activeCount=" + activeCount +
                    ", useCount=" + useCount);
            }
            if ((loginTimeout > 0) && (seconds >= loginTimeout)) {
                break;
            }

            // Return an existing connection from the pool if there is one
            synchronized (connections) {
                if (!connections.isEmpty()) {

                    // Allocate the first available connection
                    GenericConnection connection =
                        (GenericConnection) connections.removeFirst();
                    if (log.isInfoEnabled()) {
                        log.info("   Found available connection");
                    }

                    // Make sure this connection is not stale
                    connection.setClosed(false);
                    try {
                        ping(connection);
                    } catch (SQLException e) {
                        log.warn("   Connection stale, releasing");
                        try {
                            connection.getConnection().close();
                        } catch (SQLException f) {
                            ;
                        }
                        activeCount--;
                        continue;
                    }

                    // unclose the connection's wrapper and return it
                    useCount++;
                    if (log.isInfoEnabled()) {
                        log.info("   Return allocated connection, activeCount=" +
                                 activeCount + ", useCount=" + useCount);
                    }

                    return(connection);

                }
            }

            // Create a new connection if we are not yet at the maximum
            if (activeCount < maxCount) {
                Connection connection = createConnection();
                if (connection != null) {
                    try {
                        ping(connection);
                    } catch (SQLException e) {
                        throw e;
                    }
                    useCount++;
                    if (log.isInfoEnabled()) {
                        log.info("   Return new connection, activeCount=" +
                                 activeCount + ", useCount=" + useCount);
                    }

                    return (connection);
                }
            }

            // Wait for an existing connection to be returned
            if (log.isInfoEnabled()) {
                log.info("   Sleep until next test");
            }
            try {
                Thread.sleep(1000);
                seconds++;
            } catch (InterruptedException e) {
                ;
            }

        }

        // We have timed out awaiting an available connection
        if (log.isInfoEnabled()) {
            log.info("   Timeout awaiting connection");
        }
        throw new SQLException
            ("getConnection: Timeout awaiting connection");

    }


    /**
     * Attempt to establish a database connection.  <b>WARNING</b> - The
     * specified username and password are not supported by this
     * implementation.
     *
     * @param username Database username for this connection
     * @param password Database password for this connection
     *
     * @exception SQLException if a database access error occurs
     */
    public Connection getConnection(String username, String password)
        throws SQLException {

        throw new SQLException(SQLEXCEPTION_GETCONNECTION); // Not implemented

    }


    /**
     * Return the login timeout for this data source.
     *
     * @exception SQLException if a database access error occurs
     */
    public int getLoginTimeout() throws SQLException {

        return (this.loginTimeout);

    }



    /**
     * Return the log writer for this data source.
     *
     * @exception SQLException if a database access error occurs
     */
    public PrintWriter getLogWriter() throws SQLException {

        return (this.logWriter);

    }


    /**
     * Set the login timeout for this data source.
     *
     * @param loginTimeout The new login timeout
     *
     * @exception SQLException if a database access error occurs
     */
    public void setLoginTimeout(int loginTimeout) throws SQLException {

        this.loginTimeout = loginTimeout;

    }


    /**
     * Set the log writer for this data source.
     *
     * @param logWriter The new log writer
     *
     * @exception SQLException if a database access error occurs
     */
    public void setLogWriter(PrintWriter logWriter) throws SQLException {

        this.logWriter = logWriter;

    }


    // --------------------------------------------------------- Public Methods


    /**
     * Close all connections that have been created by this data source.
     *
     * @exception SQLException if a database access error occurs
     */
    public void close() throws SQLException {

        if (closed)
            throw new SQLException("close:  Data Source already closed");
        if (log.isDebugEnabled()) {
            log.debug(" close()");
        }

        // Shut down all active connections
        while (activeCount > 0) {
            GenericConnection conn = (GenericConnection) getConnection();
            conn.getConnection().close();
            activeCount--;
        }

        // Mark this data source as having been closed and release our driver
        closed = true;
        driver = null;

    }


    /**
     * Open the initial connections that are appropriate for this data source.
     *
     * @exception SQLException if a database access error occurs
     */
    public void open() throws SQLException {

        // Have we already been opened?
        if (driver != null)
            return;
        if (log.isDebugEnabled()) {
            log.debug(" open()");
        }

        // Instantiate our database driver
        try {
            driver = (Driver) applicationInstance(driverClass);
        } catch (Throwable t) {
            throw new SQLException("open: " + t);
        }

        // Create the initial minimum number of required connections
        synchronized (connections) {
            for (int i = 0; i < minCount; i++) {
                connections.addLast(createConnection());
            }
        }

        closed = false;

    }


    /**
     * Return a string representation of this component.
     */
    public String toString() {

        StringBuffer sb = new StringBuffer("GenericDataSource[");
        sb.append("activeCount=");
        sb.append(activeCount);
        sb.append(", autoCommit=");
        sb.append(autoCommit);
        sb.append(", closed=");
        sb.append(closed);
        if (description != null) {
            sb.append(", description=");
            sb.append(description);
        }
        sb.append(", driverClass=");
        sb.append(driverClass);
        sb.append(", loginTimeout=");
        sb.append(loginTimeout);
        sb.append(", maxCount=");
        sb.append(maxCount);
        sb.append(", minCount=");
        sb.append(minCount);
        sb.append(", password=");
        sb.append(password);
        sb.append(", readOnly=");
        sb.append(readOnly);
        sb.append(", url=");
        sb.append(url);
        sb.append(", useCount=");
        sb.append(useCount);
        sb.append(", user=");
        sb.append(user);
        sb.append("]");
        return (sb.toString());

    }


    // ------------------------------------------------------ Protected Methods


    /**
     * Create, configure, and return a new JDBC Connection that has been
     * wrapped in our corresponding wrapper.
     *
     * @exception SQLException if a database access error occurs
     */
    protected synchronized Connection createConnection() throws SQLException {

        if (activeCount < maxCount) {
            if (log.isInfoEnabled()) {
                log.info("   createConnection()");
            }
            Connection conn = driver.connect(url, properties);
            activeCount++;
            return (new GenericConnection(this, conn, autoCommit, readOnly));
        }

        log.error("   createConnection() returning null");

        return (null);

    }


    /**
     * Log the specified message to our log writer, if we have one.
     *
     * @param message The message to be logged
     */
    protected void log(String message) {

        if (logWriter != null) {
            logWriter.print("GenericDataSource[");
            logWriter.print(description);
            logWriter.print("]: ");
            logWriter.println(message);
        }

    }


    /**
     * Log the specified message and exception to our log writer, if we
     * have one.
     *
     * @param message The message to be logged
     * @param throwable The exception to be logged
     */
    protected void log(String message, Throwable throwable) {

        if (logWriter != null) {
            logWriter.print("GenericDataSource[");
            logWriter.print(description);
            logWriter.print("]: ");
            logWriter.println(message);
            throwable.printStackTrace(logWriter);
        }

    }


    /**
     * Perform any configured <code>pingCommand</code> and/or
     * <code>pingQuery</code> on the specified connection, returning any
     * SQLException that is encountered along the way.
     *
     * @param conn The connection to be pinged
     */
    protected void ping(Connection conn) throws SQLException {

        if (pingCommand != null) {

            if (log.isDebugEnabled()) {
                log.debug("    ping(" + pingCommand + ")");
            }

            Statement stmt = conn.createStatement();
            try {
                stmt.execute(pingCommand);
                stmt.close();
            } catch (SQLException e) {
                log.warn("ping failed:  " + e.getMessage(), e);

                try {
                    if (stmt != null) {
                        stmt.close();
                    }
                } catch (SQLException f) {
                    ;
                }
                throw e;
            }

        }

        if (pingQuery != null) {

            if (log.isDebugEnabled()) {
                log.debug("    ping(" + pingQuery + ")");
            }

            ResultSet rs = null;
            Statement stmt = conn.createStatement();
            try {
                rs = stmt.executeQuery(pingQuery);
                while (rs.next()) {
                    ;
                }
                rs.close();
                stmt.close();
            } catch (SQLException e) {
                log.warn("ping failed: " + e.getMessage(), e);

                try {
                    if (rs != null)
                        rs.close();
                } catch (SQLException f) {
                    ;
                }
                try {
                    if (stmt != null)
                        stmt.close();
                } catch (SQLException f) {
                    ;
                }
                throw e;
            }

        }

    }


    // -------------------------------------------------------- Package Methods


    /**
     * Return this connection to the available connection pool.
     *
     * @param conn The connection being returned
     */
    void returnConnection(GenericConnection conn) {

        if (log.isInfoEnabled()) {
            log.info("  releaseConnection(), activeCount=" + activeCount +
                ", useCount=" + (useCount - 1));
        }

        synchronized (connections) {
            connections.addLast(conn);
            useCount--;
        }

    }


}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?