我尝试在 play 框架内自行管理连接,并将 jooq 连接提供程序实现为:
public class PlayConnectionProvider implements ConnectionProvider {
private Connection connection = null;
@Override
public Connection acquire() throws DataAccessException {
if (connection == null) {
connection = DB.getConnection();
}
return connection;
}
@Override
public void release(Connection released) throws DataAccessException {
if (this.connection != released) {
throw new IllegalArgumentException("Expected " + this.connection + " but got " + released);
}
try {
if (connection.getAutoCommit() == true) {
connection.close();
connection = null;
}
} catch (SQLException e) {
Logger.error("Error closing connection " + connection, e);
}
}
}
但是,当我调用execute()时,jooq似乎总是会调用acquire()并创建一个新连接,而不是使用现有连接。我发现新的连接是通过execute()函数中的DefaultExecuteContext获取的:
public final Connection connection() {
ConnectionProvider provider = this.connectionProvider != null?this.connectionProvider:this.configuration.connectionProvider();
if(this.connection == null && provider != null) {
this.connection(provider, provider.acquire());
}
return this.connection;
}
有什么方法可以配置execute()的连接吗?
最佳答案
你说得对,jOOQ 总是打电话 acquire()
在每个 execute()
调用的开始处。但它也调用 release()
最后,您似乎正在自己重置缓存的连接
if (connection.getAutoCommit() == true) {
connection.close();
connection = null;
}
...因为 Play 的 DB.getConnection()
返回一个打开自动提交的连接
关于线程安全的说明
请注意,如果您以这种方式缓存连接,ConnectionProvider
将不再是线程安全的,因此包含它的所有对象也将不再是线程安全的(包括 Configuration
and DSLContext
)。维护线程安全的一种方法是将连接存储在 ConnectionProvider
ThreadLocal
中
关于java - Jooq 使用现有连接进行 fetchOne 或执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27663548/