在 JOOQ 中,如果我直接使用底层连接,我的事务状态是不是保持不变?

Posted

技术标签:

【中文标题】在 JOOQ 中,如果我直接使用底层连接,我的事务状态是不是保持不变?【英文标题】:In JOOQ, if I directly use the underlying connection, is my transactional status maintained?在 JOOQ 中,如果我直接使用底层连接,我的事务状态是否保持不变? 【发布时间】:2018-07-10 12:45:36 【问题描述】:

假设我有一个 JOOQ DSLContext 对象,我需要下拉到 JDBC Connection 对象的级别来执行一些非 JOOQ 逻辑。 (就我而言,我想使用 Postgres 驱动程序的 CopyManager 对象)。

如果我的DSLContext 是事务性的,那么直接在Connection 上执行的操作会被同一个事务包装吗?我正在使用 JOOQ 的默认事务提供程序。

例如(Kotlin 代码,但对 Java 用户应该是相当透明的)

dsl.transaction  transactionConfig ->
    val transactionalDSL = DSL.using(transactionConfig)
    transactionalDSL.connection  connection ->
        val manager = CopyManager(connection as BaseConnection)
        manager.copyInto(table, inputStream, fields)
    

【问题讨论】:

【参考方案1】:

您的 API 使用正确。

优化 API 使用

使用DSLContext.transaction(TransactionalRunnable) 时重要的是使用参数配置,您将其称为transactionConfig 用于事务边界内的所有数据库交互(不是外部dsl 引用,它保持未修改并可能返回新连接来自连接池)。

换句话说,transactionConfig 是一个 Configuration,它保证始终从事务的范围返回相同的 JDBC Connection,而不管您的 DataSource / ConnectionProvider 配置如何。

使用线程绑定事务

以上是 jOOQ 的保证,当然你也可以保证线程绑定事务也在较低级别,例如:

通过使用 jOOQ ThreadLocalTransactionProviderDSLContext.transaction(ContextTransactionRunnable),如果您的逻辑如下所示:

dsl.transaction  () ->
    dsl.connection  connection ->
        val manager = CopyManager(connection as BaseConnection)
        manager.copyInto(table, inputStream, fields)
    

通过使用线程绑定的事务连接池或数据源。在这种情况下,您的 dsl.configuration().connectionProvider() 应该返回与 transactionConfig.connectionProvider() 相同的连接,这对 jOOQ 是透明的。

【讨论】:

【参考方案2】:

从实验上看,答案似乎是肯定的。

【讨论】:

以上是关于在 JOOQ 中,如果我直接使用底层连接,我的事务状态是不是保持不变?的主要内容,如果未能解决你的问题,请参考以下文章

JOOQ DAO 使用事务支持

jOOQ 和 Spring 事务管理

在 Hibernate 事务中执行 jOOQ 语句

如何从反应式 MariaDB 连接创建 JOOQ DSLContext

声明性事务和 TransactionAwareDataSourceProxy 与 JOOQ 结合的问题

使用 Jooq 进行集成测试