我有一个使用tomcat 7和MYSQL运行的网站。它在专用服务器上运行。我正在使用简单的连接池和简单的DAO&#39>
下面列出的课程:
我还附加了服务器上所有localhost连接的屏幕截图。我使用类似的DAO和相同的连接池在不同的服务器上运行另一个应用程序,我只在该服务器上看到4个连接。
为什么会有这么多的连接,有没有办法将它追溯到我的应用程序,看看为什么这么多产生或这是正常的?
public class ConnectionPool {
private static ConnectionPool pool = null;
private static DataSource dataSource = null;
public synchronized static ConnectionPool getInstance()
{
if (pool == null)
{
pool = new ConnectionPool();
}
return pool;
}
private ConnectionPool()
{
try
{
InitialContext ic = new InitialContext();
dataSource = (DataSource) ic.lookup("java:comp/env/jdbc/DBNAME");
}
catch(Exception e)
{
e.printStackTrace();
}
}
public Connection getConnection()
{
try
{
return dataSource.getConnection();
}
catch (SQLException sqle)
{
sqle.printStackTrace();
return null;
}
}
public void freeConnection(Connection c)
{
try
{
c.close();
}
catch (SQLException sqle)
{
sqle.printStackTrace();
}
catch (NullPointerException npe){
npe.printStackTrace();
}
}
}
DAO
public static DefaultMetaInfo loadDefaultMetaData() {
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
String query = "SELECT META_TAG, TITLE_TAG FROM SITE_SETTINGS";
try {
ps = connection.prepareStatement(query);
rs = ps.executeQuery();
if (rs.next()){
DefaultMetaInfo settings = new DefaultMetaInfo();
settings.setMetaTag(rs.getString("META_TAG"));
settings.setTitleTag(rs.getString("TITLE_TAG"));
return settings;
}
} catch(SQLException e) {
e.printStackTrace();
return null;
} finally {
DaoUtil.closeResultSet(rs);
DaoUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
return new DefaultMetaInfo();
}
上下文
<?xml version='1.0' encoding='utf-8'?>
<Context>
<Resource name="jdbc/DBNAME"
auth="Container"
type="javax.sql.DataSource"
maxActive="1200"
maxIdle="30"
maxWait="10000"
testOnBorrow="true"
validationQuery="select 1"
removeAbandoned="true"
removeAbandonedTimeout="60"
logAbandoned="true"
username="user"
password="pw"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/dbname?autoReconnect=true"/>
</Context>
答案 0 :(得分:1)
如果您注意到池中的几乎所有连接都处于SLEEP
状态。
在loadDefaultMetaData()
方法的finally块中,您使用了以下语句为您释放连接并将其返回到已配置的连接池。
pool.freeConnection(connection);
此语句在该连接上释放您的“预订”并将其返回到池中。它不一定会关闭底层的实际数据库连接。有趣的是,freeConnection(connection)
无法阻止您在connection
之后再次使用free
对象(如果您仍然引用它)。
由于它可以保持打开状态(通常是),因此池层可以解释未关闭的PreparedStatement
或ResultSet
作为仍然忙的指示。
您将能够检查或调试Connection对象以在运行时识别其状态,以确认这一点。
此问题的实际解决方案是RTM并配置连接池&amp;策略正确,如下面的参考网址所述。
Shishir
答案 1 :(得分:1)
您的配置状态为maxIdle=30
,您似乎有少于30个空闲(休眠)连接。对我来说,这看起来像是预期的行为。
Shishir Kumar已经表示,当回到游泳池时,连接不一定会被关闭。原因是创建连接实际上是一项昂贵的操作,因此您通常希望将它们保持打开并重用它们 - 您还配置的validationQuery
用于检查连接是否仍然有效。
恕我直言您看到的是使用连接池时的预期行为。另外,请检查您是否真的需要(并且可以处理)1200 maxActive
个连接。这看起来非常高。如果你进入需要那么多开放连接的区域,你会想要有超过30个空闲。