我有如下代码:
fun <T> withTempTableTxn(
ctx: DSLContext,
tempTableSelectAs: org.jooq.Select<*>,
txnBlock: (DSLContext, org.jooq.Name) -> T,
): T {
val uuid = UUID.randomUUID().toString().replace("-", "_")
val tempTableName = DSL.name("temp_table_$uuid")
val createTempTable = DSL.createGlobalTemporaryTable(tempTableName).`as`(tempTableSelectAs)
return ctx.transactionResult { txn ->
txn.dsl().execute(createTempTable)
val res = txnBlock(txn.dsl(), tempTableName)
txn.dsl().execute(DSL.dropTemporaryTableIfExists(tempTableName))
res
}
}
private fun updateMutation(
mutationRequest: MutationRequest,
op: UpdateMutationOperation,
ctx: DSLContext,
): MutationOperationResult {
// The rows that the temporary table will be populated with
val tempTableRows = DSL
.selectFrom(DSL.table(DSL.name(op.table.value)))
.where(/* ... */)
return withTempTableTxn(ctx, tempTableRows) { txn, tempTableName ->
// ...
}
}
运行此命令时,似乎找不到临时表。
请注意,如果我用常规表替换temporaryTable
,则一切正常
如果我把.also { println(ctx.render(it)) }
加到createTempTable
上,我们得到:
Creating temp table:
create temporary table `temp_table_e2fd79a5_4589_41df_9972_8ff9b216300a`
as
select *
from `Chinook`.`Artist`
where `Artist`.`Name` = 'foobar'
13:48:02 ERROR traceId=, parentId=, spanId=, sampled= [io.ha.ap.ExceptionHandler] (executor-thread-0) Uncaught exception: org.jooq.exception.DataAccessException: SQL [update `temp_table_e2fd79a5_4589_41df_9972_8ff9b216300a`
set
`Name` = 'foobar new'
where `temp_table_e2fd79a5_4589_41df_9972_8ff9b216300a`.`Name` = 'foobar'];
Table 'Chinook.temp_table_e2fd79a5_4589_41df_9972_8ff9b216300a' doesn't exist
1条答案
按热度按时间fcg9iug31#
From the docs:
创建表时可以使用TEMPORARY关键字。TEMPORARY表仅在当前会话中可见,并且在会话关闭时会自动删除。这意味着两个不同的会话可以使用相同的临时表名,而不会相互冲突,也不会与现有的同名非TEMPORARY表冲突。
其他RDBMS具有临时表,其元数据在会话/事务之间共享,仅在提交时截断数据,但在MySQL中不截断。
就jOOQ而言,最有可能的解释是您使用
txn.dsl()
(事务1)创建和删除表,但您使用ctx
运行txnBlock
,ctx
也在作用域中,但运行的是不同的事务,因此它看不到您的txn
的临时表。