【问题标题】:How to get the underlying connection inside a transaction using jOOQ?如何使用 jOOQ 获取事务中的底层连接?
【发布时间】:2015-12-02 20:08:01
【问题描述】:

我在现有项目中使用 jOOQ,该项目也使用一些自定义 JDBC 代码。在jOOQ transaction 中,我需要调用其他一些 JDBC 代码,并且我需要通过活动连接,以便所有内容都在同一个事务中。

我不知道如何检索 jOOQ 事务中的底层连接。

create.transaction(configuration -> {
    DSLContext ctx = DSL.using(configuration);

    // standard jOOQ code
    ctx.insertInto(...);

    // now I need a Connection
    Connection c = ctx.activeConnection(); // not real, this is what I need
    someOtherCode(c, ...);
});

阅读文档并稍微了解一下源代码,我最好的选择是:

configuration.connectionProvider().acquire()

但在这个特定的用例中,这个名称有点误导。我不想要新的连接,只想要当前的。我认为这是要走的路,因为配置是派生的,我总是会得到相同的连接,但我不确定,我在文档中找不到答案。

【问题讨论】:

    标签: java jdbc transactions java-8 jooq


    【解决方案1】:

    jOOQ 的 API 不对“当前”连接的存在做任何假设。根据您对ConnectionProviderTransactionProvider 等的具体实现,这可能会也可能不会。

    不过,您的解决方法通常没问题。只要确保您遵循ConnectionProvider 的 SPI 合同即可:

    Connection c = null;
    try {
        c = configuration.connectionProvider().acquire();
        someOtherCode(c, ...);
    }
    finally {
        configuration.connectionProvider().release(c);
    }
    

    例如,当您使用 jOOQ 的 DefaultTransactionProvider 时,上述情况很好。

    请注意,有一个待处理的功能请求 #4552 将允许您在 ConnectionProvider 及其对 acquire()release() 的调用的上下文中运行代码。这就是它的样子:

    DSL.using(configuration)
       .connection(c -> someOtherCode(c, ...));
    

    【讨论】:

    • 感谢@LukasEder 的快速答复。我正在使用DefaultTransactionProviderConnectionProviderDataSourceConnectionProvider 而不是 DefaultConnectionProvider。我已经看到 ConnectionProvider.release() 方法在后者中什么都不做,并且在前者中关闭了连接。 DefaultTransactionProvider 在文档中说打算与DefaultConnectionProvider 一起工作。我有麻烦了吗? ;-) 看来我可能会过早地终止交易。
    • @sargue:不,你没有遇到麻烦。本地的Configuration 派生自您自己的ConfigurationDefaultTransactionProvider 在本地使用 DefaultConnectionProvider 并在事务范围内保留 Connection。我怀疑这值得更多文档
    • 谢谢@LukasEder。对答案进行了一些编辑,并被接受为当前最佳解决方案。也许交易提供者上的方法会有用? configuration.transactionProvider().currentConnection() 将在 NoTransactionProvider 上返回 null 或在其他不支持此功能的更奇特的提供程序上抛出一些异常。如果您认为它可能有用,我可以在 GitHub 中创建一个问题。
    • 好吧,我的编辑被拒绝了,所以我把它放在这里是因为我真的认为它可以改善答案。 >>> 即使release() 调用似乎关闭或回滚了它没有的连接。每当您使用create.transaction() 启动事务时,派生配置在内部使用一个新的ConnectionProvider,它会一遍又一遍地重用相同的连接,直到事务结束。这个ConnectionProvider 是使用从原始配置的ConnectionProvider 获取的一个连接初始化的DefaultConnectionProvider
    • @sargue:编辑:你刚刚遇到了堆栈溢出警察。恭喜 :)。 currentConnection() 方法:我们不能再向TransactionProvider 添加方法。如果我们需要另一种方法,我们将需要另一种方法......
    猜你喜欢
    • 2018-07-10
    • 1970-01-01
    • 2017-03-07
    • 2022-09-25
    • 2011-04-14
    • 2011-06-02
    • 1970-01-01
    • 2022-01-25
    • 2016-02-12
    相关资源
    最近更新 更多