未包装的连接是否被重用?
Is unwrapped connection reused?
我有一个 spring 组件,如下所示:
@Component
class FooComponent {
@Autowired
private DataSource dataSource;
public void execute() {
try (SQLServerConnection connection = dataSource.getConnection().unwrap(SQLServerConnection.class)) {
// some logic here with connection
}
}
}
我必须打开连接,因为我正在使用一些来自 Microsoft JDBC 驱动程序的 API(如果我只是通过 dataSource.getConnection()
,它会抛出异常)。
所以我的问题是:
我在 execute
方法中正确获取连接?那段代码能引起"connection leaks"吗?
我问这个是因为在某些时候我在日志中看到了类似这样的错误:Could not get JDBC Connection; nested exception is org.apache.tomcat.jdbc.pool.PoolExhaustedException
。 (我不是在问如何解决这个错误或它意味着什么)
So my question is: I'm correctly getting the connection in execute method?
不,池 return 的连接代理而非真实连接代理(参见 ProxyConnection)。
而proxy的close
方法是"overridden"到return连接池:
if (compare(CLOSE_VAL,method)) {
if (connection==null) return null; //noop for already closed.
PooledConnection poolc = this.connection;
this.connection = null;
pool.returnConnection(poolc);
return null;
}
}
但是当你这样做时
try (SQLServerConnection connection = dataSource.getConnection().unwrap(SQLServerConnection.class))
close
方法在实际连接上调用,而不是在代理上调用。连接未 return 发送到池中,最终池抛出 PoolExhaustedException
。
修复方法如下:
try (Connection connection = dataSource.getConnection()) { // proxy is returned to the pool
SQLServerConnection c = connection.unwrap(SQLServerConnection.class));
// Work with SQLServerConnection
}
另外请记住,您应该将展开的连接保持在您获取它时的相同状态
我有一个 spring 组件,如下所示:
@Component
class FooComponent {
@Autowired
private DataSource dataSource;
public void execute() {
try (SQLServerConnection connection = dataSource.getConnection().unwrap(SQLServerConnection.class)) {
// some logic here with connection
}
}
}
我必须打开连接,因为我正在使用一些来自 Microsoft JDBC 驱动程序的 API(如果我只是通过 dataSource.getConnection()
,它会抛出异常)。
所以我的问题是:
我在 execute
方法中正确获取连接?那段代码能引起"connection leaks"吗?
我问这个是因为在某些时候我在日志中看到了类似这样的错误:Could not get JDBC Connection; nested exception is org.apache.tomcat.jdbc.pool.PoolExhaustedException
。 (我不是在问如何解决这个错误或它意味着什么)
So my question is: I'm correctly getting the connection in execute method?
不,池 return 的连接代理而非真实连接代理(参见 ProxyConnection)。
而proxy的close
方法是"overridden"到return连接池:
if (compare(CLOSE_VAL,method)) {
if (connection==null) return null; //noop for already closed.
PooledConnection poolc = this.connection;
this.connection = null;
pool.returnConnection(poolc);
return null;
}
}
但是当你这样做时
try (SQLServerConnection connection = dataSource.getConnection().unwrap(SQLServerConnection.class))
close
方法在实际连接上调用,而不是在代理上调用。连接未 return 发送到池中,最终池抛出 PoolExhaustedException
。
修复方法如下:
try (Connection connection = dataSource.getConnection()) { // proxy is returned to the pool
SQLServerConnection c = connection.unwrap(SQLServerConnection.class));
// Work with SQLServerConnection
}
另外请记住,您应该将展开的连接保持在您获取它时的相同状态