16

I use jOOQ 3.8 and Spring Boot 1.4.1. I see that jOOQ uses a mechanism to guarantee the handling of transactions.

If I define a method annotated as transactional and inside a execute two insert, are they executed in the same transaction, e.g.

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

will all the executed insert rollback in case of exception? Will they be executed in one transaction?

Or, should I do as follows:

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

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

And what happens if I use the annotation and the jOOQ transaction as follows:

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

Will the changes in the transaction be committed regardless of the exception? (I would expect it)

mat_boy
  • 12,998
  • 22
  • 72
  • 116

1 Answers1

21

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

jOOQ doesn't actually do that. jOOQ provides an API for convenient transaction usage through lambdas. The API, however, is implemented by you (or indirectly, by Spring) through the jOOQ TransactionProvider SPI.

Using spring only (the easiest)

Given:

DSLContext ctx = ...

If you do this:

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

You're not using jOOQ's transaction API at all, you're using only spring, which is perfectly fine for jOOQ.

Using jOOQ (possibly with spring behind the scenes)

If you do this:

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

Then you use jOOQ's transaction API, which you may or may not configure to be implemented using spring transactions. By default, jOOQ will implement transactions via JDBC directly.

Using both APIs

However, this:

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

Currently (jOOQ 3.8) does not work without you implementing a rather sophisticated TransactionProvider that detects spring's declarative transaction scope in the current thread's context.

Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
  • 1
    Thanks for the answer. So, what is the benefit of using jOOQ transactions (second case) even with Spring behind the scenes? Isn't better and clearer to use Spring transaction mechanism? Moreover, if there is a benefit in the approach number two, is [this](http://www.baeldung.com/spring-boot-support-for-jooq) the way to integrate jOOQ in the transaction management? – mat_boy Oct 12 '16 at 14:13
  • 1
    The jOOQ transaction API was mostly designed for people who work with jOOQ+JDBC only, e.g. in a very slim architecture (e.g. microservice) or in a batch job. The main benefit is readability (in my opinion). Spring doesn't have these lambda-transactions yet. But if you find using Spring more robust, then don't use jOOQ's transaction API. Your link shows how you can use jOOQ with spring for case #1. – Lukas Eder Oct 12 '16 at 22:29
  • 1
    Thanks for your time. I appreciated the insights! – mat_boy Oct 13 '16 at 07:34
  • @LukasEder would you mind checking if this answer needs an update with the latest version of Spring and Jooq. I see an JooqAutoConfiguration class that seems to do all that is needed to use Spring transactions in Jooq. – rcomblen Apr 20 '18 at 08:46
  • @rcomblen: Good question, I'm not up to date with Spring Boot's latest features. I pinged some people who might know... Otherwise, feel free to create your own answer once you find out. – Lukas Eder Apr 20 '18 at 09:41
  • what is the "create" object in second example? Is it a DSLcontext instance? – ruiruige1991 Nov 11 '18 at 10:26
  • @user3978288: Yes. I'll fix the answer accordingly – Lukas Eder Nov 11 '18 at 17:57
  • 1
    Acually for me "Spring transactions" just don't work when I mark service method as `@Transactional`. But usual Spring Data service methods work perfectly. Jooq included via `spring-boot-starter-jooq` – chill appreciator Jun 29 '20 at 15:21
  • @standalone: Can you please ask a new question with details? – Lukas Eder Jun 29 '20 at 17:04
  • @LukasEder Do you know if the answer for "using both APIs" has changed in recent versions of jOOQ or Spring? – Jordie Aug 28 '23 at 16:49
  • 1
    @Jordie: I don't think it has changed? – Lukas Eder Aug 29 '23 at 07:16
  • It hasn't, I got an error that Spring doesn't support the nested transaction case in the end. Thank you – Jordie Aug 29 '23 at 13:28