0

以下のコードは、この例外を生成します。

java.sql.SQLException: Invalid state, the CallableStatement object is closed.
    at net.sourceforge.jtds.jdbc.JtdsCallableStatement.checkOpen(JtdsCallableStatement.java:120)
    at net.sourceforge.jtds.jdbc.JtdsStatement.getConnection(JtdsStatement.java:1207)
    at net.sourceforge.jtds.jdbc.JtdsResultSet.getConnection(JtdsResultSet.java:409)
    at net.sourceforge.jtds.jdbc.JtdsResultSet.close(JtdsResultSet.java:470)
    at org.apache.tomcat.dbcp.dbcp.DelegatingResultSet.close(DelegatingResultSet.java:152)
    at 

以下のこのコードは、上記のエラーを生成する場合がありますが、生成しない場合もあります。

   private void doRequest(HttpServletRequest request) throws IOException, ServletException {
        CallableStatement stmt = null;
        ResultSet rs = null;
        String someString;
        try {
            this.connectDB();
            stmt = this.conn.prepareCall("{call sp_SomeSP1(?)}");
            stmt.setLong(1, someFunc());

            rs = stmt.executeQuery();

            while (rs.next()) {
                if (rs.getInt(1)==someOtherFunc()) {
                    someString = rs.getString(2);
                    break;
                }
            }

            stmt = conn.prepareCall("{call sp_someSP(?, ?)}");
            stmt.setLong(1, someFunc());
            stmt.setTimestamp(2, new Timestamp(getFrom().getTime()));

            rs = stmt.executeQuery();
            if (rs.next()) {
                lastUpdated = rs.getTimestamp("LastUpdated");
            }

            request.setAttribute("lastUpdated", lastUpdated);

            LOGGER.debug("Forwarding to view...");
            getServletContext().getRequestDispatcher("/SomeJSP.jsp").forward(this.request, this.response);

        } catch (NamingException e) {
            LOGGER.error("Database connection lookup failed", e);
            sendError("Server Error");
        } catch (SQLException e) {
            LOGGER.error("Query failed", e);
            sendError("Server Error");
        } catch (IllegalStateException e) {
            LOGGER.error("View failed", e);
        } finally {
            try {
                if (rs!=null) rs.close(); 
            } catch (NullPointerException e) {
                LOGGER.error("Result set closing failed", e);
            } catch (SQLException e) {
                LOGGER.error("Result set closing failed", e);
            }
            try {
                if (stmt!=null) stmt.close();
            } catch (NullPointerException e) {
                LOGGER.error("Statement closing failed", e);
            } catch (SQLException e) {
                LOGGER.error("Statement closing failed", e);
            }
            try {
                this.closeDB();
            } catch (NullPointerException e) {
                LOGGER.error("Database connection closing failed", e);
            } catch (SQLException e) {
                LOGGER.error("Database connection closing failed", e);
            }
        }

これが意味するのは、doRequest()ほとんどの場合正しく機能しますが、HTTPエラー500が発生することがあり、Tomcatログを確認すると次のように表示されます。

java.sql.SQLException: Invalid state, the CallableStatement object is closed.
4

3 に答える 3

4

サーブレット(conn変数)でメンバー変数を使用しているようです。ただし、サーブレットは通常、複数のスレッドから同時に呼び出すことができます。複数のスレッドが誤って同じ接続を使用/閉じないようにするにはどうすればよいですか?

于 2012-12-19T03:23:43.047 に答える
1
stmt.setLong(1, someFunc());
stmt.setTimestamp(3, new Timestamp(getFrom().getTime()));

そうなる

stmt.setLong(1, someFunc());
stmt.setTimestamp(2, new Timestamp(getFrom().getTime()));
于 2012-12-19T03:17:15.733 に答える
0

org.apache.tomcat.dbcp.dbcp.DelegatingResultSet.closeスタックトレースにこのエラーメッセージが表示されているので、結果セットを閉じているときにエラーが発生しているようです

結果セットを閉じる前に、結果セットがまだ開いているかどうかを確認するために、結果セットの条件を変更することをお勧めします。

    if (rs!=null && ! rs.isClosed()){
        //resultset is there and not in closed state
        rs.close(); 
    }
于 2012-12-19T03:24:06.150 に答える