jOOQ和Spring事务管理

2022-09-03 13:50:27

我使用jOOQ 3.8和Spring Boot 1.4.1。我看到jOOQ使用一种机制来保证交易的处理

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

@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(可能在幕后使用弹簧)

如果这样做:

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)如果不实现一个相当复杂的TransmissionEr来检测当前线程上下文中spring的声明性事务范围,就无法工作。


答案 2

推荐