0

這是我最近碰到的事情。JdbcTemplate undertanding

我的春天的JdbcTemplate的理解是,你可以打電話:

JdbcTemplate template = new JdbcTemplate(dataSource); 
Connection conn = template.getDataSource().getConnection(); 

它返回您使用傳入的數據源來自JdbcTemplate的一個連接。如果我那麼做:

template.getDataSource().getConnection().close(); 

這是否只是得到另一個連接並關閉它,創建一個泄漏資源,還是它得到你正在使用的連接?

編輯:

我已經寫在一個2層的方法是編寫JDBC語句的老派低級別的方式(與連接,語句和結果集):

public void execute(String tableName) { 
    try { 
     Class.forName("com.ibm.as400.access.AS400JDBCDriver"); 
     Connection con = DriverManager.getConnection("jdbc:as400://viper", "******", "******"); 
     Statement select = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); 

     ResultSet rs = select.executeQuery ("SELECT * FROM ******." + tableName); 
     logger.info("start clearing: " + tableName); 

     while (rs.next()) { 
      rs.deleteRow(); 
     } 
     logger.info("Step1 done clearing: " + tableName); 

     ConnectionRecycler.recycleConnection(select, true, con); 

     execute2(tableName); 
    } catch (Exception eX) { 
     logger.error(eX); 
    } 
} 

其他方法:

public void execute2(String tableName) { 

    String nameOS = System.getProperty("os.name"); 
    String sql = (nameOS.equals("OS/400")) ? "DELETE from " + tableName : 
     "DELETE from " + tableName + " with none"; 

    JdbcTemplate templateSNPJ; 

    templateSNPJ = new JdbcTemplate(this.snpjDataSource); 
    templateSNPJ.update(sql); 

    logger.info("Finished clearing: " + tableName); 
    getServiceManager().unregisterService(this); 
} 

我有這樣正確清理資源。第二種方法,是使用:

JdbcTemplate.update(sqlCommand); 

但看來,JdbcTemplate的是保持連接的比池活得更長配置爲。

我讀SO這篇文章:Database connection management in Spring並躲避到具有使用數據源配置與在bean定義像這樣一個破壞法=閉合參數:

<bean id="SnpjDataSource" class="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean" destroy-method="close"> 
     <property name="uniqueResourceName" value="@#$$datasource"/> 
     <property name="driverClassName" value="com.ibm.as400.access.AS400JDBCDriver"/> 
     <property name="url" value="jdbc:as400://VIPER/******"/> 
     <property name="user" value="FuManChu"/> 
     <property name="password" value="*%[email protected]^%$*#^[email protected]^[email protected]"/> 
     <property name="maxPoolSize" value="10"/> 
     <property name="reapTimeout" value="40"/> 
    </bean> 

EDIT2:

ConnectionRecycler.recycleConnection方法:

public static void recycleConnection(Statement state, boolean closeConnection, 
     Connection connect) { 
    try { 
     state.close(); 
     if (closeConnection) { 
      connect.close(); 
     } 
    } catch (SQLException sqlEx) { 
     logger.error("Error closing resources! ", sqlEx); 
    } 
} 

回答

0

這取決於您的數據源。如果您想確定使用相同的連接,請撥打#getConnection撥打電話或使用SingleConnectionDataSource。請注意,您必須在線程安全的env中使用此數據源。它本身不是線程安全的。另外,你不應該直接訪問Connection。這是JdbcTemplate的整點。它隱藏了JDBC內部...避免了連接泄露等風險。

+0

出於興趣,您爲什麼需要訪問連接? – wmorrison365 2013-04-23 15:31:15

+0

@ wmorricon365我在頂部添加了更多信息。我正在辯論把它放在那裏第一次。 Spring應該管理後端資源的關閉,但似乎並沒有清理資源。我的連接池沒有連接。這個類是在計時器線程中運行的唯一的東西。我也縮小了JdbcTemplate的泄漏範圍。如果你看看我的ConnectionRecycler.recycleConnection()方法,它非常簡單。 – ResourceReaper 2013-04-23 15:44:53

+0

嗨喬希。我注意到你正在使用'AtomikosNonXADataSourceBean'並且有連接池。我想知道你是否知道這個DS如何提供連接並回收它們。它的'#close'實際上是關閉連接還是重新將它添加到池中。在看到失敗並且超出'com.atomikos.datasource.pool.ConnectionPool#borrowConnectionTimeout'之前,您要做多少次迭代?即連接是否可以重複使用?另外,您是否嘗試過在測試中使用替代數據源(將問題隔離到JDBCTemplate,DS或您的配置?) – wmorrison365 2013-04-23 16:29:44