调用JooQ DSLContext的.close()时,什么时候关闭连接(如果有的话)? [英] When is a Connection closed when calling JooQ DSLContext's .close(), if at all?
问题描述
这是我正在编写的使用JooQ 3.7.0的类的代码(不相关的部分已被剥离);请注意 DSLContext
的 AutoCloseable
功能的使用:
Here is the code of a class which I am writing which uses JooQ 3.7.0 (the irrelevant parts have been stripped); note the uses of the AutoCloseable
feature of DSLContext
:
public final class JooqPerMethodMetricWriter
implements PerMethodMetricWriter
{
private static final Logger LOGGER
= LoggerFactory.getLogger(JooqPerMethodMetricWriter.class);
// [snip]
private final DSLContext jooq;
public JooqPerMethodMetricWriter(final Connection connection,
final Instant instant)
throws IOException
{
// [snip]
jooq = DSL.using(connection);
}
private void writeCsv(final Configuration configuration)
{
// [snip]
try (
final DSLContext context = DSL.using(configuration);
final Reader reader = Files.newBufferedReader(csvPath);
) {
final Loader<PermethodMetricsRecord> loader = context
.loadInto(PERMETHOD_METRICS)
.loadCSV(reader)
.fields(PERMETHOD_METRICS.fields())
.execute();
LOGGER.info("{} lines stored in database", loader.stored());
} catch (IOException e) {
throw new RuntimeException("Cannot open CSV for reading", e);
}
// BREAKPOINT 1
}
@Override
public void close()
throws IOException
{
jooq.transaction(this::writeCsv);
jooq.close();
// BREAKPOINT 2
Files.delete(csvPath);
}
// [snip]
}
如果相关完全使用的数据库是PostgreSQL(9.4.x)。
If relevant at all, the database used is PostgreSQL (9.4.x).
在上面的代码中,我有两个断点。当我调试时,我看到:
In the code above, I have two breakpoints. When I debug, I see that:
- 在第一个断点
configuration.connectionProvider()。acquire() .isClosed()
是错误的... - 在第二个断点处,
jooq.configuration()。connectionProvider( ).acquire()。isClosed()
也是 假。
- at the first breakpoint,
configuration.connectionProvider().acquire().isClosed()
is false... - at the second breakpoint,
jooq.configuration().connectionProvider().acquire().isClosed()
is also false.
我糊涂了。我作为构造函数参数收到的 Connection
怎么了?我是否需要自己 .close()
?
I'm confused. What happened to the Connection
which I have received as a constructor parameter? Do I need to .close()
it myself?
附带的问题,这次与 Loader
有关:我保留默认值,因此 .commitNone()
;鉴于我在事务处理中运行加载程序,如果我尝试使用 .commit< somethingElse>()
代替,例如 .commitAfter(1000)
?
Side question, this time with regards to the Loader
: I leave the defaults, therefore .commitNone()
; given that I run the loader within a transacation, would it make a difference at all if I tried and .commit<somethingElse>()
instead, for instance .commitAfter(1000)
?
推荐答案
DSLContext $ c在Java 8发行版的jOOQ 3.7中,$ c>变为
AutoCloseable
。 DSLContext.close()
方法的Javadoc解释了此 close()
调用的语义:
DSLContext
became AutoCloseable
with the Java 8 distributions of jOOQ 3.7. The DSLContext.close()
method's Javadoc explains the semantics of this close()
call:
如果构建此
DSLContext
时已分配了任何资源,则关闭基础资源。
Close the underlying resources, if any resources have been allocated when constructing this
DSLContext
.
某些 DSLContext
构造函数,例如 DSL.using(String)
, DSL.using(String,属性)
或 DSL.using(String,String,String)
分配一个连接
资源,其中是 DSLContext
实现外部无法访问的。因此,必须通过此 close()
方法来进行适当的资源管理。
Some DSLContext
constructors, such as DSL.using(String)
, DSL.using(String, Properties)
, or DSL.using(String, String, String)
allocate a Connection
resource, which is inaccessible to the outside of the DSLContext
implementation. Proper resource management must thus be done via this close()
method.
只有在构造 DSLContext
时分配的资源才会被释放。不是您传递给 DSLContext
的资源。就您而言,您没有在此 try-with-resources
语句中分配任何资源,因此在该语句的末尾没有任何可释放的内容:
Only resources allocated when you constructed the DSLContext
will be released. Not resources that you passed to the DSLContext
. In your case, you are not allocating any resources in this try-with-resources
statement, so there is nothing to be released at the end of it:
try (DSLContext context = DSL.using(configuration); ...) { ... }
如果您在此处分配了新的 Connection
,则情况会有所不同:
This would be different if you allocated a new Connection
right there:
try (DSLContext context = DSL.using("jdbc:h2:~/test", "sa", ""); ...) { ... }
关于您的问题:
Regarding your questions:
我很困惑。作为构造函数参数收到的Connection发生了什么情况?
I'm confused. What happened to the Connection which I have received as a constructor parameter?
没事。您必须自己控制其生命周期,因为jOOQ对连接生命周期策略一无所知。
Nothing. You must govern its lifecycle yourself as jOOQ doesn't know anything about your connection lifecycle strategy.
我是否需要.close()它
Do I need to .close() it myself?
是的。
这篇关于调用JooQ DSLContext的.close()时,什么时候关闭连接(如果有的话)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!