在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) } }
你的API使用是正确的。
最佳的API使用
使用DSLContext.transaction(TransactionalRunnable)
时,重要的一点是使用参数配置,您可以在事务边界内为所有数据库交互调用transactionConfig
(不是外部dsl
引用,它不会被修改,并且可能会从连接池返回一个新的连接)。
换句话说, transactionConfig
是一个Configuration
,它保证始终从事务的作用域返回相同的JDBC Connection
,而不管你的DataSource
/ ConnectionProvider
配置如何。
使用线程绑定事务
以上是jOOQ的保证,当然你也可以保证线程绑定的事务处于较低的级别,例如:
-
通过与
DSLContext.transaction(ContextTransactionRunnable)
一起使用jOOQThreadLocalTransactionProvider
,如果您的逻辑如下所示:dsl.transaction { () -> dsl.connection { connection -> val manager = CopyManager(connection as BaseConnection) manager.copyInto(table, inputStream, fields) } }
-
通过使用线程绑定的事务连接池或数据源。 在这种情况下,您的
dsl.configuration().connectionProvider()
应该返回与transactionConfig.connectionProvider()
相同的连接,并且这对于jOOQ是透明的。
实验上,答案似乎是肯定的。