在 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 ThreadLocalTransactionProvider
和 DSLContext.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 中,如果我直接使用底层连接,我的事务状态是不是保持不变?的主要内容,如果未能解决你的问题,请参考以下文章
如何从反应式 MariaDB 连接创建 JOOQ DSLContext