jOOQ 和 Spring 事务管理

jOOQ and Spring transaction management

我使用 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(...);
}

所有执行的insert在异常情况下会回滚吗?它们会在一笔交易中执行吗?

或者,我应该做如下操作:

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(":)");
}

事务中的更改是否会被提交而不考虑异常? (我希望如此)

I see that jOOQ uses a mechanism to guarantee the handling of transactions.

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

仅使用 spring(最简单)

鉴于:

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 实现交易。

同时使用 APIs

然而,这:

@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 检测当前线程上下文中 spring 的声明性事务范围的情况下无法工作。