您的位置:首页 > 编程语言 > Java开发

Spring的JdbcTemplate使用,是否还需要手工或者aop指定关闭conn连接( 使用JdbcTemplate是否需要关闭连接)

2011-11-25 15:02 519 查看
JdbcTemplate类使用DataSource得到一个数据库连接。然后,他调用StatementCreator实例创建要执行的语句。下一步,他调用StatementCallBack完成。

一旦StatementCallBack返回结果,JdbcTemplate类完成所有必要清理工作关闭连接。如果StatementCreator或StatementCallBack抛出异常,JdbcTemplate类会捕获他们,并转换为Spring数据访问异常。



看一个JdbcTemplate里面的比较核心的一个方法:

view
plaincopy
to clipboardprint?

//-------------------------------------------------------------------------

//
Methods dealing with prepared statements

//-------------------------------------------------------------------------

public Object
execute(PreparedStatementCreator psc, PreparedStatementCallback action)

throws DataAccessException
{

Assert.notNull(psc, "PreparedStatementCreator
must not be null");

Assert.notNull(action, "Callback
object must not be null");

if (logger.isDebugEnabled())
{

String
sql = getSql(psc);

logger.debug("Executing
prepared SQL statement" +
(sql != null ? "
[" +
sql + "]" : ""));

}

Connection
con = DataSourceUtils.getConnection(getDataSource());

PreparedStatement
ps = null;

try {

Connection
conToUse = con;

if (this.nativeJdbcExtractor
!= null &&

this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativePreparedStatements())
{

conToUse
= this.nativeJdbcExtractor.getNativeConnection(con);

}

ps
= psc.createPreparedStatement(conToUse);

applyStatementSettings(ps);

PreparedStatement
psToUse = ps;

if (this.nativeJdbcExtractor
!= null)
{

psToUse
= this.nativeJdbcExtractor.getNativePreparedStatement(ps);

}

Object
result = action.doInPreparedStatement(psToUse);

handleWarnings(ps);

return result;

}

catch (SQLException
ex) {

//
Release Connection early, to avoid potential connection pool deadlock

//
in the case when the exception translator hasn't been initialized yet.

if (psc instanceof ParameterDisposer)
{

((ParameterDisposer)
psc).cleanupParameters();

}

String
sql = getSql(psc);

psc
= null;

JdbcUtils.closeStatement(ps);

ps
= null;

DataSourceUtils.releaseConnection(con,
getDataSource());

con
= null;

throw getExceptionTranslator().translate("PreparedStatementCallback",
sql, ex);

}

finally {

if (psc instanceof ParameterDisposer)
{

((ParameterDisposer)
psc).cleanupParameters();

}

JdbcUtils.closeStatement(ps);

DataSourceUtils.releaseConnection(con,
getDataSource());

}

}

显然,我们在finally里面看到了关闭调用,在看看这个关闭调用方法内部:

view
plaincopy
to clipboardprint?

/**

*
Close the given Connection, obtained from the given DataSource,

*
if it is not managed externally (that is, not bound to the thread).

*
@param con the Connection to close if necessary

*
(if this is <code>null</code>, the call will be ignored)

*
@param dataSource the DataSource that the Connection was obtained from

*
(may be <code>null</code>)

*
@see #getConnection

*/

public static void releaseConnection(Connection
con, DataSource dataSource) {

try {

doReleaseConnection(con,
dataSource);

}

catch (SQLException
ex) {

logger.debug("Could
not close JDBC Connection",
ex);

}

catch (Throwable
ex) {

logger.debug("Unexpected
exception on closing JDBC Connection",
ex);

}

}

/**

*
Actually close the given Connection, obtained from the given DataSource.

*
Same as {@link #releaseConnection}, but throwing the original SQLException.

*
<p>Directly accessed by {@link TransactionAwareDataSourceProxy}.

*
@param con the Connection to close if necessary

*
(if this is <code>null</code>, the call will be ignored)

*
@param dataSource the DataSource that the Connection was obtained from

*
(may be <code>null</code>)

*
@throws SQLException if thrown by JDBC methods

*
@see #doGetConnection

*/

public static void doReleaseConnection(Connection
con, DataSource dataSource) throws SQLException
{

if (con
== null)
{

return;

}

if (dataSource
!= null)
{

ConnectionHolder
conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);

if (conHolder
!= null &&
connectionEquals(conHolder, con)) {

//
It's the transactional Connection: Don't close it.

conHolder.released();

return;

}

}

//
Leave the Connection open only if the DataSource is our

//
special SmartDataSoruce and it wants the Connection left open.

if (!(dataSource instanceof SmartDataSource)
|| ((SmartDataSource) dataSource).shouldClose(con)) {

logger.debug("Returning
JDBC Connection to DataSource");

con.close();

}

}

主要下面这几行代码:

view
plaincopy
to clipboardprint?

//
Leave the Connection open only if the DataSource is our

//
special SmartDataSoruce and it wants the Connection left open.

if (!(dataSource instanceof SmartDataSource)
|| ((SmartDataSource) dataSource).shouldClose(con)) {

logger.debug("Returning
JDBC Connection to DataSource");

con.close();

}

哦,可以看到大部分情况下是自动关闭,除非你使用的SmartDataSource,且SmartDataSource指定了允许关闭。

有些时候,你引入了JdbcTemplate或者DaoSupport,但是有时还需要自己额外的拿到conn进行操作,如下:

jdbcTemplate.getDataSource().getConnection()

那么,你应该就需要关闭连接了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐