在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)一起使用jOOQ ThreadLocalTransactionProvider ,如果您的逻辑如下所示:

     dsl.transaction { () -> dsl.connection { connection -> val manager = CopyManager(connection as BaseConnection) manager.copyInto(table, inputStream, fields) } } 
  • 通过使用线程绑定的事务连接池或数据源。 在这种情况下,您的dsl.configuration().connectionProvider()应该返回与transactionConfig.connectionProvider()相同的连接,并且这对于jOOQ是透明的。

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