JOOQ & 交易

JOOQ & Transaction

我看过JOOQTransaction Management版块
它是开始交易使用 jooq 交易 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(...);
});

它的回滚是隐式的。
但是我想自己提交和回滚。 我的项目不是基于 Spring 和 Spring 引导。 JOOQ有这样的api吗?

// 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

这部分告诉我可以实现您自己的 org.jooq.TransactionProvider 并将其提供给您的配置以覆盖 jOOQ 的默认行为
这个接口方法参数是TransactionContext,我不知道这是什么...

与 jOOQ 的隐式交易

你可以使用jOOQ的事务API来实现你想做的事情:

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) { ... }
});

以上示例使用隐式嵌套事务,使用 JDBC 个保存点,每当您创建嵌套 transaction() 时。如果您捕捉到您抛出的异常,那么您将不会回滚整个事务,而只会回滚嵌套的事务。

当然,也可以使用类似的方法来回滚整个事务。

使用 jOOQ 的程序化交易

除了您已经看到的基于隐式 lambda / 异常的功能之外,还有一个待处理的功能请求来添加对程序事务的支持 API,类似于 JDBC: https://github.com/jOOQ/jOOQ/issues/5376

目前,你不能单独使用 jOOQ 来完成你想要的,但是你总是可以使用 JDBC 和 jOOQ,例如(假设 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();
});

注意,我使用 JDBC Savepoint 是因为我从你的示例中假设这就是你想要做的。如果不是,当然,您可以省略保存点并始终回滚整个事务。