When is a Connection closed when calling JooQ DSLContext's .close(), if at all?

自作多情 提交于 2019-12-13 02:00:19

问题


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]    
}

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:

  • at the first breakpoint, configuration.connectionProvider().acquire().isClosed() is false...
  • at the second breakpoint, jooq.configuration().connectionProvider().acquire().isClosed() is also false.

I'm confused. What happened to the Connection which I have received as a constructor parameter? Do I need to .close() it myself?


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)?


回答1:


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:

Close the underlying resources, if any resources have been allocated when constructing this DSLContext.

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.

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); ...) { ... }

This would be different if you allocated a new Connection right there:

try (DSLContext context = DSL.using("jdbc:h2:~/test", "sa", ""); ...) { ... }

Regarding your questions:

I'm confused. What happened to the Connection which I have received as a constructor parameter?

Nothing. You must govern its lifecycle yourself as jOOQ doesn't know anything about your connection lifecycle strategy.

Do I need to .close() it myself?

Yes.



来源:https://stackoverflow.com/questions/33594328/when-is-a-connection-closed-when-calling-jooq-dslcontexts-close-if-at-all

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!