我正在将Axis2与Apache Tomcat一起使用 . 我需要Web服务的客户端能够查询数据库,所以我在互联网上发现,通过将以下资源添加到Tomcat的上下文,它将自动创建一个连接池:
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已经是poolable) . 我希望通过这种方式,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,但是异常说它已关闭 . 也许这不是重用prepareStatement的方法,但是我怎么能这样做呢?我读到,如果我在同一个查询上调用conn.prepareStatement,jdbc将从缓存中返回PreparedStatement(它不会被再次解析),但我不确定它是否为真 .
1 回答
有一个名为c3p0的项目专门用于处理你遇到的一个案例 . 该网站位于https://sourceforge.net/projects/c3p0/,此处http://www.mchange.com/projects/c3p0/它处理数据源JNDI绑定,连接池和语句池 . 还有一个关于使用这个库和servlet的人的stackoverflow的引用what-is-a-good-strategy-for-caching-prepared-statements-in-tomcat