问题
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