2012-10-18 100 views
0

我使用Axis2和Apache Tomcat。我需要的Web服务的客户端能够查询数据库,所以我认为,通过将下面的资源到Tomcat的情况下,它会自动创建一个连接池在互联网上找到:PreparedStatement和Axis2

 
Resource name="jdbc/TestDB" auth="Container" 
       type="javax.sql.DataSource" 
       removeAbandoned="true" 
       removeAbandonedTimeout="30" 
       maxActive="80" 
       maxIdle="30" 
       maxWait="10000" 
       username="user" 
       password="" 
       driverClassName="org.postgresql.Driver" 
       url = "jdbc:postgresql://localhost:5432/mydb" 
       useUnicode="true" 
       characterEncoding="utf-8" 
       characterSetResults="utf8" 
       validationQuery="/* ping */ SELECT 1" 

它似乎正在工作,但现在我想要做的是重复使用相同的PreparedStatement,因此每次客户端发出请求时都不会进行分析。所以,我使PreparedStatement对所有客户端连接都是静态的,当我创建它时,我调用statement.setPoolable(true),据我所知,这是多余的(PreparedStatement已经可用)。我希望通过这种方式,PreparedStatement不会绑定到单个连接上。仍然出现错误:

java.sql.SQLException:org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement with address * is closed。

奇怪的是,如果我在做任何设置之前调用statement.isClosed(),它将返回false。然后,我设置了一些东西,并抛出异常。

的代码是:

try { 
     Connection conn; 

     Context envCtx = (Context) new InitialContext().lookup("java:comp/env"); 

     DataSource ds = (DataSource) envCtx.lookup("jdbc/TestDB"); 
     conn = ds.getConnection();  

     if(statement == null){ 
     //statement is static, so it won't be null at the second call     
      statement = conn.prepareStatement(query); 
      statement.setPoolable(true);   
     } 
     if(statement.isClosed()){ 
      statement = conn.prepareStatement(query); 
      //it never gets here 
     } 
     else{ 
      Logger.getLogger(HelloAxisWorld.class.getName()).log(Level.INFO, "STATEMENT IS NOT CLOSED", new Object()); 
      //it always gets here 
     } 

     statement.setString(1, par1); //here, the second call throws an exception 
     ResultSet rs = statement.executeQuery(); 
     while (rs.next()) { 
      cur_value = rs.getInt("cur_value"); 
     }   
     rs.close(); 

     conn.close(); 

    }catch (Exception ex) {    
     Logger.getLogger(HelloAxisWorld.class.getName()).log(Level.SEVERE, null, ex);   
    } 

我不明白为什么statement.isClosed返回false,但随后的异常说,它是封闭的。也许这不是重用预处理语句的方式,但那我该怎么做呢?我读过,如果我在同一个查询中调用conn.prepareStatement,jdbc将从缓存中返回PreparedStatement(它不会再被解析),但我不确定它是否属实。

回答