与 SqlServer 的连接未在 for 循环中关闭 java

Connection to SqlServer not closing in for loop java

我不确定这方面的最佳做法,但我的总体问题是我无法弄清楚为什么我的连接没有关闭。

我基本上是遍历一个列表,然后将它们插入 table。在我将它们插入 table 之前,我检查并确保它不是重复的。如果是,我更新该行而不是插入它。截至目前,在调试让我知道我的连接未关闭之前,我只能进行 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?

很高兴您正在努力稳健地 close() 您的资源,但这太复杂了。

除非您使用的是相当旧的 Java 版本(Java 7 之前的版本),否则您可以使用 try-with-resources,这确实简化了这些东西。在一个逻辑工作单元中使用两个不同的连接会引起误解。资源应该 close() 尽可能在本地使用,而不是将所有事情推迟到最后。

您的异常处理很危险。如果发生您不理解的异常,您可能想要打印其堆栈跟踪,但您的代码应该表明您所做的任何事情都不起作用。你吞下了异常,甚至通知 "Save Complete" 尽管它。

综上所述,MERGE 语句可能会让您的生活变得更轻松,I think SQL Server supports

这是一个(未经测试、未编译的)示例重组:

try ( Connection con = cpds2.getConnection() ) {
    for (Object itemId: aList.getItemIds()){
        boolean id_is_present = false;
        try ( PreparedStatement stmt = con.prepareStatement("select [ID] from [DB].[dbo].[Table1] WHERE [ID] = ?") ) {
            stmt.setInt(1, aList.getItem(itemId).getBean().getID());
            try ( ResultSet rs = stmt.executeQuery() ) {
               id_is_present = rs.next();
            }
        }
        if ( id_is_present ) {
            System.out.println("Duplicate");
            try ( PreparedStatement stmt = con.prepareStatement("UPDATE [DB].[dbo].[Table1] SET [DateSelected]=GETDATE() where  [ID] = ?") ) {
                stmt.setInt(1,aList.getItem(itemId).getBean().getID());
                stmt.executeUpdate();
            }
         } else {
             System.out.println("Insertion");
             try ( PreparedStatement stmt = con.prepareStatement("INSERT INTO [DB].[dbo].[Table1] ([ID],[FirstName], [LastName],[DateSelected]) VALUES (?,?,?,?)") ) {
                 stmt.setInt(1,aList.getItem(itemId).getBean().getID() );
                 stmt.setString(2,aList.getItem(itemId).getBean().getFirstName());
                 stmt.setString(3,aList.getItem(itemId).getBean().getLastName() );
                 stmt.setTimestamp(4, new Timestamp(new Date().getTime()));
                 stmt.executeUpdate();
             }
         }
    }
    Notification.show("Save Complete");    
}