【发布时间】:2017-09-13 10:02:34
【问题描述】:
我不确定这方面的最佳做法,但我的总体问题是我无法弄清楚为什么我的连接没有关闭。
我基本上是在遍历一个列表,然后将它们插入到一个表中。在将它们插入表格之前,我会检查并确保它不是重复的。如果是,我更新行而不是插入它。截至目前,在调试让我知道我的连接未关闭之前,我只能进行 13 次迭代。
由于我有 2 个连接,我无法确定我应该在哪里关闭我的连接,我试图使用其他示例来提供帮助。这是我得到的:
Connection con = null;
PreparedStatement stmt = null;
PreparedStatement stmt2 = null;
ResultSet rs = null;
Connection con2 = null;
for (Object itemId: aList.getItemIds()){
try {
con = cpds2.getConnection();
stmt = con.prepareStatement("select [ID] from [DB].[dbo].[Table1] WHERE [ID] = ?");
stmt.setInt(1, aList.getItem(itemId).getBean().getID());
rs = stmt.executeQuery();
//if the row is already there, update the data/
if (rs.isBeforeFirst()){
System.out.println("Duplicate");
stmt2 = con2.prepareStatement("UPDATE [DB].[dbo].[Table1] SET "
+ "[DateSelected]=GETDATE() where [ID] = ?");
stmt2.setInt(1,aList.getItem(itemId).getBean().getID());
stmt2.executeUpdate();
}//end if inserting duplicate
else{
con2 = cpds2.getConnection();
System.out.println("Insertion");
stmt.setInt(1, aList.getItem(itemId).getBean().getID());
//Otherwise, insert them as if they were new
stmt2 = con.prepareStatement("INSERT INTO [DB].[dbo].[Table1] ([ID],[FirstName],"
+ "[LastName],[DateSelected]) VALUES (?,?,?,?)");
stmt2.setInt(1,aList.getItem(itemId).getBean().getID() );
stmt2.setString(2,aList.getItem(itemId).getBean().getFirstName());
stmt2.setString(3,aList.getItem(itemId).getBean().getLastName() );
stmt2.setTimestamp(4, new Timestamp(new Date().getTime()));
stmt2.executeUpdate();
}//End Else
}catch(Exception e){
e.printStackTrace();
}//End Catch
finally{
try { if (rs!=null) rs.close();} catch (Exception e) {}
try { if (stmt2!=null) stmt2.close();} catch (Exception e) {}
try { if (stmt!=null) stmt.close();} catch (Exception e) {}
try { if (con2!=null) con2.close();} catch (Exception e) {}
try {if (con!=null) con.close();} catch (Exception e) {}
}//End Finally
} //end for loop
Notification.show("Save Complete");
这是我的池连接:
//Pooled connection
cpds2 = new ComboPooledDataSource();
try {
cpds2.setDriverClass("net.sourceforge.jtds.jdbc.Driver");
} catch (PropertyVetoException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //loads the jdbc driver
cpds2.setJdbcUrl( "jdbc:jtds:sqlserver://SERVERNAME;instance=DB" );
cpds2.setUser("username");
cpds2.setPassword("password");
cpds2.setMaxStatements( 180 );
cpds2.setDebugUnreturnedConnectionStackTraces(true); //To help debug
cpds2.setUnreturnedConnectionTimeout(2); //to help debug
我的主要问题是,我关闭我的连接对吗?我的连接池设置正确吗? 我应该在 for 循环内部还是外部关闭连接?
c3p0 有问题吗?还是 JTDS?
【问题讨论】:
-
恕我直言,您应该在
for循环之外建立连接,然后在循环完成/退出时关闭。否则,您将在每个循环中获得一个新连接。是的,池化得到了缓解,但仍然可以避免很多流失。 -
很抱歉,这听起来像是一个非常愚蠢的问题,但是在同一个连接关闭之前多次重复使用准备好的语句是否安全?
-
是的。您甚至可以在循环外准备语句,并在每次迭代时更新参数。此外,除非您连接到两个不同的数据源(而且它看起来不像您),否则您可以删除
con2并使用con处理所有内容。可能是微优化,但如果你经常循环这个,它就会加起来。
标签: java sql-server c3p0 jtds