【发布时间】:2011-06-23 20:26:09
【问题描述】:
我正在使用 Hibernate 开发一个 Java Web 应用程序,但其中一部分我想使用 JDBC,因为我正在动态创建查找表。
使用我的网络应用几分钟后,我收到此错误:
com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: 数据源拒绝建立 连接,来自服务器的消息:“太 许多连接”
我知道不推荐使用 session.connection(),但我只想获取底层的 JDBC 连接。我尝试使用 session.doWork() 但错误仍然像以前一样发生。
代码如下:
领域层:
/**
* Goes through the list of lookupTableAbstractions and persists each one
* @param lookupData
*/
public void updateLookupValues( List<LookupTableAbstraction> lookupData )
{
lookupTablesData.dropAllLookupTables(lookupData);
lookupTablesData.createLookupTables(lookupData);
for (LookupTableAbstraction lookupTable : lookupData)
lookupTablesData.persistLookupTableValues(lookupTable);
}
数据层:
public LookupTableAbstraction getLookupTable( String tableName )
{
LookupTableAbstraction lookupTable = new LookupTableAbstraction();
Session session = getSessionFactory().openSession();
String sqlQuery = "select value from " + tableName;
List<String> lookupTableValues = session.createSQLQuery(sqlQuery).list();
session.close();
lookupTable.setTableName(tableName);
for (String value : lookupTableValues)
lookupTable.addValue(value);
return lookupTable;
}
/**
* Persists the passed in lookup table.
* The lookup table that is used is determine by
* the tableName field of the passed in lookupTable
* @param lookupTable
*/
public void persistLookupTableValues( LookupTableAbstraction lookupTable )
{
Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
Connection connection = null;
try
{
connection = getJDBCConnectionFromHibernate(session);
Statement stmt = connection.createStatement();
String tableName = lookupTable.getTableName();
for (String value : lookupTable.getValues() )
{
String sql = " insert into " + tableName +
" (value) " +
" values " +
"('" + value + "')";
System.out.println(sql);
stmt.executeUpdate(sql);
}
stmt.close();
}
catch( Exception e )
{
System.out.println("Exception(persistLookupTableValues): " + e.getMessage());
e.printStackTrace();
}
finally
{
try {
tx.commit();
connection.close();
session.close();
} catch (SQLException e) {
System.out.println("Exception(persistLookupTableValues): " + e.getMessage());
e.printStackTrace();
}
}
}
/**
* Drop's all lookup tables.
* It drops each table based off the lookupTableAbstractions in the passed in list
* @param lookupData
*/
public void dropAllLookupTables( List<LookupTableAbstraction> lookupData )
{
Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
Connection connection = null;
try
{
connection = getJDBCConnectionFromHibernate(session);
Statement stmt = null;
for (LookupTableAbstraction lookupTableAbstraction : lookupData) {
stmt = connection.createStatement();
stmt.executeUpdate("drop table " + lookupTableAbstraction.getTableName());
}
stmt.close();
}
catch( Exception e )
{
System.out.println("Exception(dropAllLookupTables): " + e.getMessage());
e.printStackTrace();
}
finally
{
try {
tx.commit();
connection.close();
session.close();
} catch (SQLException e) {
System.out.println("Exception(dropAllLookupTables): " + e.getMessage());
e.printStackTrace();
}
}
}
/**
* Creates all lookup tables, one for each lookupTableAbstraction
* in the passed in list
* @param lookupData
*/
public void createLookupTables( List<LookupTableAbstraction> lookupData )
{
Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
Connection connection = null;
try
{
connection = getJDBCConnectionFromHibernate(session);
Statement stmt = null;
for (LookupTableAbstraction lookupTableAbstraction : lookupData) {
stmt = connection.createStatement();
stmt.executeUpdate("create table " + lookupTableAbstraction.getTableName() +
" ( ID int(11) auto_increment, " +
" value text, " +
" primary key (ID) )");
}
stmt.close();
}
catch( Exception e )
{
System.out.println("Exception(createLookupTables): " + e.getMessage());
e.printStackTrace();
}
finally
{
try {
tx.commit();
connection.close();
session.close();
} catch (SQLException e) {
System.out.println("Exception(createLookupTables): " + e.getMessage());
e.printStackTrace();
}
}
}
protected Connection getJDBCConnectionFromHibernate( Session session )
{
return session.connection();
}
感谢您的任何建议
【问题讨论】:
-
您肯定会以某种方式泄漏连接。要验证这一点,您可以监控应用程序正在使用的连接数吗?如果启用了统计信息,您可以从会话工厂获取此值。 session.getSessionFactory().getStatistics().getConnectionCount().
-
您能看到您在代码中登录的任何异常吗?
-
嗨 Pace,我启用了统计功能,并且在我使用该应用程序时,它始终保持在 1 个连接。嗨,axtavt,唯一抛出的异常是当我收到“用户过多”异常时。
-
嗯,恐怕我不知道是什么导致了这个问题。您知道您是否使用池连接提供程序?连接池可能只是设置为大于 MySQL 允许的值(默认情况下我认为这是 100),并且这种错误配置直到现在才暴露出来。调试问题的另一种方法是下载 Hibernate 源代码并找出调用 Connection.close() 时到底发生了什么(Hibernate 返回的连接实际上是代理,而不是真正的底层连接)