Java.sql连接在特定服务器上关闭异常

时间:2011-11-16 11:07:05

标签: java sql jboss

每当我在My production Server上传我的应用程序时,我都会关闭Java.sql.Connection异常。生产服务器是Jboss。 我也试过QA,DEV服务器,不会发生这个问题。 我们是一个Web应用程序,每当我们遍历特定选项卡时,都会发生此异常。

这是追踪:

  

2011-11-11 14:32:12,983 ERROR [STDERR] java.sql.SQLException:关闭连接   2011-11-11 14:32:12,984 oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)的错误[STDERR]   2011-11-11 14:32:12,984错误[STDERR] at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)   2011-11-11 14:32:12,984 oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208)的错误[STDERR]   2011-11-11 14:32:12,984错误[STDERR] at oracle.jdbc.driver.PhysicalConnection.prepareStatement(PhysicalConnection.java:897)   2011-11-11 14:32:12,984错误[STDERR] at oracle.jdbc.driver.PhysicalConnection.prepareStatement(PhysicalConnection.java:816)   2011-11-11 14:32:12,984错误[STDERR] at com.amadeus.mis.usermanagement.MisDb.prepareStatement(MisDb.java:72)   2011-11-11 14:32:12,984错误[STDERR] at com.amadeus.mis.usermanagement.MisDb.getCompId(MisDb.java:1002)   2011-11-11 14:32:12,984错误[STDERR] at com.amadeus.mis.usermanagement.MisDb.loadUnLinkedUsers(MisDb.java:1033)   2011-11-11 14:32:12,984 org.apache.jsp.LinkUser_jsp._jspService(LinkUser_jsp.java:445)的错误[STDERR]   2011-11-11 14:32:12,985 org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)中的错误[STDERR]   2011-11-11 14:32:12,985错误[STDERR]在javax.servlet.http.HttpServlet.service(HttpServlet.java:717)   2011-11-11 14:32:12,985 org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:387)中的错误[STDERR]   2011-11-11 14:32:12,985 org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)中的错误[STDERR]   2011-11-11 14:32:12,985 org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)中的错误[STDERR]   2011-11-11 14:32:12,985错误[STDERR]在javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

我还附上了一个代码示例,这是发生错误的代码。

public List<String>loadLinkedUsers(String uname)
    throws Exception
    {

        List<String> userList = new ArrayList<String>();

        String[]temp=uname.split("_");
        String myschema=temp[0]+"_"+temp[1];
        if(!getUserType(uname).equalsIgnoreCase("RC"))
        {
        PreparedStatement stmt = null;

         stmt = prepareStatement("select res_user_id from"+" "+myschema+".res_user where login_id = ? and res_user_id !='Administrator'");
         stmt.setString(1,uname);

        try {

            ResultSet rs = stmt.executeQuery();
            while(rs.next())
            {

                userList.add(rs.getString(1));

            }
            rs.close();
        } catch (Exception e) {
            System.out.println("Exception"+e.getMessage());
        }
        stmt.close();
        }
        return userList;

    }

    public  int getCompId(String userName)
    {
        PreparedStatement stmt;
        int temp=0;
        try{
        stmt = prepareStatement("Select comp_id from mis.users where login_id = ?");
        stmt.setString(1,userName);
        ResultSet rs=stmt.executeQuery();
        while(rs.next())
        {
            temp=rs.getInt(1);
        }

        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

        return temp;
    }
    /**
     * Load the information about users that are not Linked to 
     * the user who is logged in.
     * (login_id, user_email, user_type_id from table mis.users)
     * @param login
     * @param users Vector that is filled with user information of type User.
     *              The previous data is not cleared. 
     * @throws SQLException
     */
    public List<String> loadUnLinkedUsers(String uname)
    throws Exception
    {

        List<String>userList = new ArrayList<String>();

        String[]temp=uname.split("_");
        String myschema=temp[0]+"_"+temp[1];
        int comp_id=getCompId(uname);

        if(!getUserType(uname).equalsIgnoreCase("RC"))
        {
        PreparedStatement stmt1=null;
        String query1="select res_user_id from"+" "+myschema+".res_user where login_id=? and res_user_id='Administrator'";
        stmt1 = prepareStatement(query1);
        stmt1.setString(1,uname);
        try {

            ResultSet rs1 = stmt1.executeQuery();
             /*if(!rs1.next())
             {
                userList.add("Administrator");
             }*/

        } catch (Exception e) {
            System.out.println("Exception"+e.getMessage());
        }

        PreparedStatement stmt = null;
        String query="SELECT u.login_id FROM mis.users u LEFT JOIN mis.user_type t ON u.user_type_id = t.user_type_id  WHERE comp_id = ? minus select res_user_id from"+" "+myschema+".res_user where login_id =?";
        stmt = prepareStatement(query);
        stmt.setInt(1,comp_id);
        stmt.setString(2,uname);

        try {

            ResultSet rs = stmt.executeQuery();
            while(rs.next())
            {
                userList.add(rs.getString(1));

            }
            rs.close();
        } catch (Exception e) {
            System.out.println("Exception"+e.getMessage());
        }
        stmt.close();
        }
        return userList;

    }

请注意,这是用于创建准备语句的函数。

protected Connection m_Connection;

    /**
     * Prepare a statement from the current connection
     * @param strSql
     * @return Prepared statement
     * @throws SQLException
     */
    protected PreparedStatement prepareStatement(String strSql) throws SQLException
    {
        logger.debug("SQL=  " + strSql);
        return m_Connection.prepareStatement(strSql);
    } 

4 个答案:

答案 0 :(得分:1)

看起来数据库在一段时间后关闭了你的连接。确保在数据源配置文件中启用check-valid-connection-sql属性并使用有效的检查SQL(例如,从双选1),以便在重新调用之前自动验证连接。还要确保您没有持有类变量中的连接对象并在多个请求中重复使用

<check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql>

答案 1 :(得分:1)

目前尚不清楚m_Connection的范围在哪里,是否重用,重复使用频率或多个线程是否可以同时访问同一连接,这可能会导致问题。

如果m_Connection保持打开并且打算由个别请求重用,可能会发生的情况是数据库驱动程序可能会在一段时间不活动后自动关闭它。

我的问题是,您是否考虑使用JNDI DataSource来查找您的连接,而不是在m_Connection缓存连接?

Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/TestDB");
Connection conn = ds.getConnection();

try {
    ... DB logic ...
} finally {
    conn.close();
}

通过这种方式,创建和管理连接的业务被委托给将汇集连接的应用服务器,因此每次拨打电话时都不会实际打开和关闭新连接。

代码的其他可能问题包括:

  • 未关闭所有ResultSet s
  • 未关闭finally块中的PreparedStatement(或getCompId未完全关闭)

答案 2 :(得分:1)

我最终通过替换classes12.jar并使用初始上下文代替驱动程序管理器来解决此问题。

答案 3 :(得分:-1)

请确保您的构建路径中有正确的apache derby jars。 您可以在解压缩的zip derby文件的lib文件夹中获取derby.jat和derbyclient.jar。