免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2961 | 回复: 2
打印 上一主题 下一主题

JDBC的连接池控制问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-01-29 15:42 |只看该作者 |倒序浏览
6可用积分
概要
      使用jdbc的数据源,同时有2个线程得到数据库连接,在各自执行DB操作时,发生异常 java.sql.SQLException: Closed Statement

相关代码

   public class Connection {

/**
* The name used to identify the cache uniquely
*/
private static final String CACHE_NAME = "Cache";

/**
* Data Source Variable
*/
private static OracleDataSource ods = null;

/**
* Connection cache manager
*/
private static OracleConnectionCacheManager connMgr = null;

/**
* Connection*/

protected Connection conn = null;

static ResourceBundle res = ResourceBundle.getBundle("XXXXXXconn";

/**
* JDBC
*/
private static String url = res.getString("url";

/**
* userid
*/
private static String userid = res.getString("userid";

/**
* passwd
*/
private static String passwd = res.getString("passwd";

public Connection() {
try{
if(ods == null){
ods = new OracleDataSource();

ods.setURL(url);
ods.setUser(userid);
ods.setPassword(passwd);

//Enable cahcing
ods.setConnectionCachingEnabled(true);

//Set the cache name
ods.setConnectionCacheName(CACHE_NAME);

Properties properties = new Properties();
properties.setProperty("MinLimit", res.getString("poolmin");
properties.setProperty("MaxLimit", res.getString("poolmax");

connMgr = OracleConnectionCacheManager
.getConnectionCacheManagerInstance();

connMgr.createCache(CACHE_NAME, ods, properties);

System.out.println("ooledConnection Initialized:" + ods);

System.out.println("MaxPoolSize:" +
ods.getConnectionCacheProperties()
.getProperty("MinLimit");
System.out.println("MinPoolSize:" +
ods.getConnectionCacheProperties()
.getProperty("MaxLimit");
}
}catch(SQLException eq){
System.err.println(eq.getMessage());
};
}

public Connection getConn() throws SQLException {

try{
System.out.println("Active connection number:" +
connMgr.getNumberOfActiveConnections(CACHE_NAME));
System.out.println("Available connection number:" +
connMgr.getNumberOfAvailableConnections(CACHE_NAME));

connMgr.refreshCache(CACHE_NAME,
OracleConnectionCacheManager.REFRESH_INVALID_CONNECTIONS);

conn = ods.getConnection();

System.out.println("Got Pooled Connection:" + conn);

DefaultContext.setDefaultContext(new DefaultContext(conn));

}catch(SQLException eq){
System.err.println(eq.getMessage());
if(!conn.isClosed()) conn.close();
}
return(conn);
}

}

Exception message
  [ 日期时间  JST] 000001dc    ERROR:Closed Statement
  [ 日期时间  JST] 000001c8 java.sql.SQLException: Closed Statement
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:20
at oracle.jdbc.driver.OracleStatement.ensureOpen(OracleStatement.java:3523)
at oracle.jdbc.driver.OracleCallableStatement.executeUpdate(OracleCallableStatement.java:4239)
at sqlj.runtime.ExecutionContext$OracleContext.oracleExecuteUpdate(ExecutionContext.java:1556)

经过:
 有2个线程,它们之间没有任何关系 

    1 线程1开始执行getConn
        1-1 执行refreshCache
        1-2 执行ods.getConnection()
    2 线程2开始执行getConn
        2-1 执行refreshCache
        2-2 执行ods.getConnection() 
    3 线程1和线程2同时取得数据库连接
    4 Exception发生

log内容:
 
000001c8 SystemOut O Active connection number?0
000001c8 SystemOut O Available connection number?3
000001dc SystemOut O Active connection number?0
000001dc SystemOut O Available connection number?2
000001c8 SystemOut O Got Pooled Connection?oracle.jdbc.driver.LogicalConnection@60f4c701
000001dc SystemOut O Got Pooled Connection?oracle.jdbc.driver.LogicalConnection@66354461
※ 最后2个log输出时间完全相同。

补充  这个系统已经运行快2年了,是第一次出现这种bug。小弟才疏学浅,还请各位大侠不吝赐教。谢谢了

论坛徽章:
0
2 [报告]
发表于 2009-01-29 19:14 |只看该作者
是statement关闭了。可能跟这段代码没有关系。检查一下在什么地方关闭了statement,又重新使用

论坛徽章:
0
3 [报告]
发表于 2009-01-30 09:14 |只看该作者
恩,我查了一下调用代码

稍微说明一下情况,大家分析一下可能的原因

  调用代码是sqlj文件,在那2个代码中,大体结构是这样的

     1  连接取得

     2  直接执行oracle的存储过程 执行语句里面没有指定具体的connetion contexts 和 execution contexts

也就是说,使用的这2个对象是在取得连接的最后一句代码中设置的,是默认的对象

           DefaultContext.setDefaultContext(new DefaultContext(conn));

      
例 调用代码
               #sql ret = { VALUES(XXXX.FUNC_XXXXX_SEL(
                        :IN a,
                        :IN b,
                        :IN c,
                        :OUT d() };

现在我担心的问题是,connetion contexts  这个东西,是线程安全的吗?每个线程都设置一遍,有影响吗?

[ 本帖最后由 wq_1228 于 2009-2-2 15:54 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP