【问题标题】:jOOQ and Spring transaction managementjOOQ 和 Spring 事务管理
【发布时间】:2017-02-20 11:46:37
【问题描述】:

我使用 jOOQ 3.8 和 Spring Boot 1.4.1。 我看到jOOQ使用了一种机制来保证handling of transactions

如果我定义一个注释为事务性的方法并在执行两个插入中,它们是否在同一个事务中执行,例如

@Transactional(propagation = Propagation.MANDATORY)
public doInsert(){
    DSL.using(configuration).insertInto(...);
    DSL.using(configuration).insertInto(...);
}

如果发生异常,所有执行的插入都会回滚吗?它们会在一笔交易中执行吗?

或者,我应该这样做:

public doInsert(){
  create.transaction(configuration -> {

    DSL.using(configuration).insertInto(...);
    DSL.using(configuration).insertInto(...);    
  });
}

如果我按如下方式使用注解和 jOOQ 事务会发生什么:

@Transactional(propagation = Propagation.MANDATORY)
public doInsert(){
  create.transaction(configuration -> {

    // Wrap configuration in a new DSLContext:
    DSL.using(configuration).insertInto(...);
    DSL.using(configuration).insertInto(...);    
  });
  throw new RuntimeException(":)");
}

无论异常是否都会提交事务中的更改? (我会期待的)

【问题讨论】:

    标签: java spring transactions jooq


    【解决方案1】:

    我看到jOOQ使用了一种机制来保证事务的处理。

    jOOQ 实际上并没有这样做。 jOOQ 提供了一个 API,可以通过 lambdas 方便地使用事务。然而,API 由您(或间接由 Spring)通过 jOOQ TransactionProvider SPI 实现。

    仅使用弹簧(最简单)

    给定:

    DSLContext ctx = ...
    

    如果你这样做:

    @Transactional(propagation = Propagation.MANDATORY)
    public doInsert(){
        ctx.insertInto(...);
        ctx.insertInto(...);
    }
    

    你根本没有使用 jOOQ 的事务 API,你只使用了 spring,这对 jOOQ 来说非常好。

    使用 jOOQ(可能在幕后使用 spring)

    如果你这样做:

    public doInsert(){
      ctx.transaction(configuration -> {
        DSL.using(configuration).insertInto(...);
        DSL.using(configuration).insertInto(...);    
      });
    }
    

    然后您使用 jOOQ 的事务 API,您可能会或可能不会将其配置为使用 spring 事务实现。默认情况下,jOOQ 会直接通过 JDBC 实现事务。

    同时使用两种 API

    但是,这个:

    @Transactional(propagation = Propagation.MANDATORY)
    public doInsert(){
      ctx.transaction(configuration -> {
    
        // Wrap configuration in a new DSLContext:
        DSL.using(configuration).insertInto(...);
        DSL.using(configuration).insertInto(...);    
      });
      throw new RuntimeException(":)");
    }
    

    目前(jOOQ 3.8)如果不实现相当复杂的TransactionProvider 将无法工作,该TransactionProvider 在当前线程的上下文中检测spring 的声明性事务范围。

    【讨论】:

    • 感谢您的回答。那么,即使在幕后使用 Spring,使用 jOOQ 事务(第二种情况)有什么好处呢?使用Spring事务机制不是更好更清晰吗?此外,如果方法二有好处,this 是在事务管理中集成 jOOQ 的方法吗?
    • jOOQ 事务 API 主要是为只使用 jOOQ+JDBC 的人设计的,例如在非常苗条的架构(例如微服务)或批处理作业中。主要的好处是可读性(在我看来)。 Spring 还没有这些 lambda 事务。但是如果你发现使用 Spring 更健壮,那么不要使用 jOOQ 的事务 API。您的链接显示了如何将 jOOQ 与 spring 一起用于案例 #1。
    • 感谢您的宝贵时间。我很欣赏这些见解!
    • @LukasEder 您是否介意检查此答案是否需要使用最新版本的 Spring 和 Jooq 进行更新。我看到了一个 JooqAutoConfiguration 类,它似乎可以完成在 Jooq 中使用 Spring 事务所需的一切。
    • @romblen:问得好,我不了解 Spring Boot 的最新功能。我联系了一些可能知道的人......否则,一旦发现,请随时创建自己的答案。
    猜你喜欢
    • 2019-01-17
    • 2016-12-02
    • 2014-02-22
    • 1970-01-01
    • 2015-07-16
    • 2019-02-24
    • 1970-01-01
    相关资源
    最近更新 更多