使用 DataSourceConnectionProvider 的 JOOQ 配置的线程安全性如何?

How thread-safe is a JOOQ Configuration with a DataSourceConnectionProvider?

我倾向于使用以下模式编写我的数据库 classes:

public class AccountDao { 
    private final Configuration configuration;

    @Inject
    public AccountDao(final @Named(ACCOUNT_DATA_SOURCE) DataSource dataSource) {
        configuration = new DefaultConfiguration().derive(dataSource).derive(SQLDialect.POSTGRES);
    }

    private UserRecord getUserById(final UUID id) {
        return using(configuration)
            .selectFrom(USER)
            .where(USER.ID.eq(id))
            .fetchOne();
    }
  
    ...

如果我创建第二个 class 也需要使用 JOOQ 代码连接到同一个数据库,我应该在什么级别共享连接?我可以使用相同的数据源创建第二个 Configuration,还是会导致并发问题?

Configuration 包含缓存,例如反射缓存,您不应每次都重新创建。理想情况下,您的 DataSource 有一个 Configuration,您可以在任何地方共享它并从您的 CDI 设置中注入。 Spring Boot 会自动为您完成。我不知道有任何 CDI/jOOQ 自动配置,但您可以轻松地自行配置。

没有线程安全保证,因为 Configuration 只是设置和 SPI 实现的集合,其中 ConnectionProvider。如果您的手动 ConnectionProvider 不是线程安全的,那么您的 Configuration 也不是。如果您在示例中使用 DataSourceConnectionProvider,那么 DataSource 的线程安全保证将被继承。在经典的 Spring / Java EE 设置中,DataSource 通常是线程绑定的,允许面向 AOP 的事务声明,因此您可以安全地在任何地方注入该实例(因为您已经注入 DataSource)

全部记录在此处: https://www.jooq.org/doc/latest/manual/sql-building/dsl-context/thread-safety/

org.jooq.Configuration, and by consequence org.jooq.DSLContext, make no thread safety guarantees, but by carefully observing a few rules, they can be shared in a thread safe way. We encourage sharing Configuration instances, because they contain caches for work not worth repeating, such as reflection field and method lookups for org.jooq.impl.DefaultRecordMapper. If you're using Spring or CDI for dependency injection, you will want to be able to inject a DSLContext instance everywhere you use it.