jOOQ 和 Spring 事务管理

Posted

技术标签:

【中文标题】jOOQ 和 Spring 事务管理【英文标题】:jOOQ and Spring transaction management 【发布时间】: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(":)");

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

【问题讨论】:

【参考方案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 的最新功能。我联系了一些可能知道的人......否则,一旦发现,请随时创建自己的答案。

以上是关于jOOQ 和 Spring 事务管理的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate 和 jOOQ 共享事务

在 Hibernate 事务中执行 jOOQ 语句

JOOQ DAO 使用事务支持

如何一起使用Spring启动,JOOQ和Flyway?

Spring boot、JOOQ和Flyway如何一起使用?

声明性事务和 TransactionAwareDataSourceProxy 与 JOOQ 结合的问题