在上一篇(
笔记中,介绍了BAE MySQL服务的使用,示例Demo也跑得很正常。
不过后来不知从什么时候开始,又变得有些许不正常了…具体表现出来是DB查询部分有时候行为怪异,有时候还提示什么什么超时什么的(request 什么 exceed limit 什么什么的,忘了复制下来了……)
几经查找,发现问题在于连接数据库的connenction的地方:
因为按照以前的习惯,我在Java里连接MySQL,都会使用连接池的方式实现。以前一直用的是org.apache.commons.dbcp 和 org.apache.commons.pool包的实现(jar包版本为commons-dbcp-1.4.jar),所以这次BAE上也是用的这一套实现。
但就在此处发现了问题。
具体流程如下
//----伪码开始--------
请求到来时,首先拿到DataSource的实例: DataSource ds = ....;
然后得到连接:Connection conn = ds.getConnection();
进行具体查询:try{ PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); }
最后关闭连接:finnaly{ rs.close(); ps.close(); conn.close(); }
//----伪码结束---------
这个过程本身没什么问题,在BAE里第一次执行时也没什么问题。
但当第二次执行的时候,问题就来了。
在正常的环境中,在连接池工作正常的情况下,每一次ds.getConnection()都可以拿到一个可用的连接;但在BAE环境中,只有第一次返回的conn对象是可用的,第二次再执行,将返回一个状态是closed的conn对象(没有进一步验证它是否就是上一次那个conn),这就导致后面的查询一定会失败。
发现这一点以后,就修改了一行代码,将
Connection conn = ds.getConnection();
改成了官方示例中的获取方式:
Connection conn = DriverManager.getConnection(cname, user, password);
然后就一切正常了……
写在此处,希望给遇到类似问题的朋友一点启发。
以上。