【发布时间】:2014-03-26 09:49:10
【问题描述】:
我们正在将我们的应用服务器从 Weblogic 迁移到 JBoss,我们面临一个由 Jboss 管理的数据源的问题,它没有关闭 Ironjacamar 包装的连接。
环境:Jboss 7.2,Ironjacamar 1.0.15,Oracle 11G
在从 Oracle 数据源获取连接时,我们使用 appserver(Weblogic/Jboss) 特定包装器将连接包装到 Oracle Connection,如下所示。如果我们不包装它,我们将无法使用 ArrayDescriptors 等 Oracle 功能。我们应该改变我们的应用程序,使其在 weblogic 和 jboss 中都可以工作。
Connectionutil.java:
public static Connection getConnection(String jndiName) throws NamingException, SQLException {
InitialContext initContext = new InitialContext();
Context envContext = (Context) initContext.lookup("java:/comp/env");
DataSource dataSource = (DataSource) envContext.lookup(jndiName);
Connection connection = dataSource.getConnection();
connection= unwrapConnection(connection);
return connection;
}
private static Connection unwrapConnection(Connection connection) throws SQLException {
if(isWeblogic) {
if(connection instanceof weblogic.jdbc.extensions.WLConnection) {
System.out.println("Datasource is maintained by Weblogc so Unwarping Weblogic JDBC Connection to oracle.jdbc.OracleConnection. Driver name is " + connection.getMetaData().getDriverName());
return (oracle.jdbc.OracleConnection) ((weblogic.jdbc.extensions.WLConnection) connection).getVendorConnection();
}
} else if(isJboss) {
if(connection instanceof org.jboss.jca.adapters.jdbc.jdk6.WrappedConnectionJDK6) {
System.out.println("Datasource is maintained by Jboss so Unwarping Jboss JDBC Connection to oracle.jdbc.OracleConnection. Driver name is " + connection.getMetaData().getDriverName());
return (oracle.jdbc.OracleConnection) ((org.jboss.jca.adapters.jdbc.jdk6.WrappedConnectionJDK6) connection).getUnderlyingConnection();
}
}
// log.debug("{called getConnection(non weblogic type) - " + connection.getMetaData().getDriverName() + "}");
return connection;
}
每当需要连接时,我们都会调用 Datasource,如下所示:
//some code
connection = Connectionutil.getConnection("jdbc/SomeDS");
finally()
{
connection.close();//closing the connection
}
这里的问题是即使在关闭来自客户端的连接之后,如果请求新连接,jboss 池也不会释放连接,池会提供其他可用连接,直到池耗尽(maxCONnections)而不重用关闭的连接。我希望 jboss 连接池管理器会负责管理连接它没有发生。
我在 Jboss 社区中找到了类似上述问题的解决方案: https://community.jboss.org/thread/72958?start=0&tstart=0 我们能够解决独立应用程序的问题,如下所示。
Connection logicalConnection= dataSource.getConnection();//got the connection from DS
Connection oracleConnection= Connectionutil.unwrapConnection(connection );//unwrapping and wrappig to oracle connection
//some code
{
finally()
{
logicalConnection.close;// here closing logical connection instead of oracle connection. Then jboss is reusing the connections.
}
但是如果 J2EE 应用程序使用像 spring 这样的框架来管理连接打开和关闭,我不明白在这种情况下如何获得容器包装的连接而不是上面的 oracle 连接?
谁能建议我解决上述问题的更好方法??
【问题讨论】:
-
您会自动获得容器包装连接,如果您使用 Spring 或其他框架,则不需要 oracleConnection。我在这里没有看到问题,或者您没有在最后一个解决方案中添加实际问题?
-
(您可以考虑将 unwrapIfWLConnection 重命名为 unwrapConnection 以匹配它实际执行的操作)
-
对不起,我的问题可能会让你感到困惑,你是对的,spring 提供了包装器连接,但最后我们需要它为许多数组描述符操作包装到 oracle 连接,所以我们实现了一个 javax.sql.DataSource getConnection 方法并配置 spring 以使用 org.springframework.jndi.JndiObjectFactoryBean 获取此连接,因此 spring 正在关闭 oracle 连接,我认为这是导致问题的原因。
标签: java jboss jboss7.x datasource connection-pooling