JOOQ & Transaction

不羁岁月 提交于 2020-07-31 05:48:48

问题


I have seen JOOQ Transaction Management section
it's start transaction use jooq transaction api,

create.transaction(configuration -> {

    // Wrap configuration in a new DSLContext:
    DSL.using(configuration).insertInto(...);
    DSL.using(configuration).insertInto(...);
    
    // Or, reuse the new DSLContext within the transaction scope:
    DSLContext ctx = DSL.using(configuration);
    ctx.insertInto(...);
    ctx.insertInto(...);
    
    // ... but avoid using the scope from outside the transaction:
    create.insertInto(...);
    create.insertInto(...);
});

It's rollback is implicit.
But I want to submit and rollback by myself. My project isn't base on Spring and Spring boot. Is JOOQ has some api like this?

// start transaction
    api.begin()
// will do handle like this many times
    dslContext.update(...)
    Object obj = dslContext.select(...)
    if (obj == null) {
        api.rollback;
    }
    dslContext.insert(...)
    Object obj1 = dslContext.select(...)
    if (obj1 == null) {
        api.rollback;
    }
    ...
    ...
// finally, if no problem:
    api.commit

this section tell I can implement your own org.jooq.TransactionProvider and supply that to your Configuration to override jOOQ's default behaviour.
this interface method params is TransactionContext, I dont known what's this...


回答1:


Implicit transactions with jOOQ

You can use jOOQ's transaction API to achieve what you want to do like this:

create.transaction(c1 -> {
    try {
        c1.dsl().transaction(c2 -> {
            c2.dsl().update(...);
            Object obj = c2.dsl().select(...);
            if (obj == null)
                throw new MyRollbackException();
        });
    }
    catch (MyRollbackException e) { ... }

    try {
        c1.dsl().transaction(c2 -> {
            c2.dsl().insert(...);
            Object obj = c2.dsl().select(...);
            if (obj == null)
                throw new MyRollbackException();
        });
    }
    catch (MyRollbackException e) { ... }
});

The above example is using implicit nested transaction using JDBC savepoints, whenever you create a nested transaction(). If you catch the exception that you're throwing yourself, then you won't roll back the entire transaction, but just the nested one.

Of course, it's possible to use a similar approach to roll back the entire transaction.

Procedural transactions with jOOQ

There's a pending feature request to add support for a procedural transaction API, similar to that of JDBC, in addition to the implicit lambda / exception based one that you've seen: https://github.com/jOOQ/jOOQ/issues/5376

Currently, you can't do what you intended with jOOQ alone, but you can always resort to using JDBC with jOOQ, e.g. (assuming autoCommit = false):

// Obtain a JDBC connection from jOOQ (alternatively, use your own)
dslContext.connection(con -> {

    // Depending on your DataSource, make sure you're always using the same JDBC connection
    DSLContext ctx = DSL.using(con);

// start transaction
    // This isn't needed with JDBC, as a Connection always implicitly starts transactions
    // when autoCommit = false

// will do handle like this many times
    Savepoint sp1 = con.setSavepoint();
    ctx.update(...)
    Object obj1 = ctx.select(...)
    if (obj1 == null) {
        con.rollback(sp1);
    }
    Savepoint sp2 = con.setSavepoint();
    ctx.insert(...)
    Object obj2 = ctx.select(...)
    if (obj2 == null) {
        con.rollback(sp2);
    }
    ...
    ...
// finally, if no problem:
    con.commit();
});

Notice, I'm using JDBC Savepoint because I'm assuming from your example that this is what you want to do. If it's not, of course, you can just omit the savepoints and always roll back the entire transaction.



来源:https://stackoverflow.com/questions/62771908/jooq-transaction

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!