Hi again,

I have rewritten the implementation now to only manipulate the
configuration before starting the transaction as you pointed out. This is
what is happening:

Configuration derivedCfg;
TransactionProvider jooqTransactionProvider = cfg.transactionProvider();
if (jooqTransactionProvider instanceof SpringTransactionProvider) {
    SpringTransactionProvider stp = (SpringTransactionProvider)
jooqTransactionProvider;
    SpringTransactionProvider localStp =
stp.derive(cfg.connectionProvider(),
TransactionDefinition.ISOLATION_SERIALIZABLE);

    derivedCfg = cfg.derive(localStp);
} else {
    // Use default configuration and transaction definition
    derivedCfg = cfg;
}

try (DSLContext ctx = new DefaultDSLContext(derivedCfg)) {
    ctx.transaction(() ->
ctx.insertInto(table("")).columns(field("")).values("").execute()); //
<-- just dummy example
}


The noisy code creating the derived config is moved into a helper class so
that I don't need to have this spread around my DAOs:

try (DSLContext ctx =
dbCon.transactionWithIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE))
{
        ctx.transaction(() -> savedResult.set(saveMethod(ctx, entity))
    );
    return savedResult.get();
}

The SpringTransactionProvider is as it was in the previous post:

/**
 * An example <code>TransactionProvider</code> implementing the {@link
TransactionProvider} contract for use with
 * Spring.
 *
 * @author Lukas Eder
 */
public class SpringTransactionProvider extends
ThreadLocalTransactionProvider implements TransactionProvider {

    private static final JooqLogger LOGGER =
JooqLogger.getLogger(SpringTransactionProvider.class);
    private DataSourceTransactionManager txMgr;
    private int transactionDefinition;

    public SpringTransactionProvider(ConnectionProvider provider,
DataSourceTransactionManager txMgr) {
        super(provider);
        this.txMgr = txMgr;
        this.transactionDefinition = PROPAGATION_NESTED;
    }

    public SpringTransactionProvider(ConnectionProvider provider,
DataSourceTransactionManager txMgr, int transactionDefinition) {
        super(provider);
        this.txMgr = txMgr;
        this.transactionDefinition = transactionDefinition;
    }

    @Override
    public void begin(TransactionContext ctx) {
        LOGGER.info("Begin transaction");

        // This TransactionProvider behaves like jOOQ's
DefaultTransactionProvider,
        // which supports nested transactions using Savepoints
        TransactionStatus tx = txMgr.getTransaction(new
DefaultTransactionDefinition(transactionDefinition));
        ctx.transaction(new SpringTransaction(tx));
    }

    @Override
    public void commit(TransactionContext ctx) {
        LOGGER.info("commit transaction");

        txMgr.commit(((SpringTransaction) ctx.transaction()).tx);
    }

    @Override
    public void rollback(TransactionContext ctx) {
        LOGGER.info("rollback transaction");

        txMgr.rollback(((SpringTransaction) ctx.transaction()).tx);
    }

    public SpringTransactionProvider derive(ConnectionProvider
provider, int transDefinition) {
        return new SpringTransactionProvider(provider, txMgr,
transactionDefinition);
    }
}


What do you think about this approach?

Cheers Steinar

On Thu, Jan 31, 2019 at 10:45 AM Lukas Eder <[email protected]> wrote:

> On Wed, Jan 30, 2019 at 9:24 PM Steinar Dragsnes <
> [email protected]> wrote:
>
>> I didn’t think I patched the current transaction, I thought I created a
>> new inner transaction with a different/derived config.
>>
>
> I don't think it will work this way. The TransactionProvider SPI should be
> in control of your entire set of nested transactions. The way your code
> looks right now, it may well be that the outer and inner transaction
> providers don't "communicate" with each other. It might as well work - I
> don't know your implementation of the TransactionProvider, but it does look
> like something the next developer might easily get wrong when modifying the
> code.
>
>
>> So if I do a config.derive before starting the transaction then I am fine?
>>
>
> That's what I would have done, yes.
>
>
>> The main problem as I can see it right now is that the
>> TransactionDefinition is hardcoded in the SpringTransactionProvider. For
>> most things that is fine but this is a special case where I must use a
>> different transaction isolation.
>>
>
> Would you mind sharing your SpringTransactionProvider?
>
> Thanks,
> Lukas
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "jOOQ User Group" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/jooq-user/FVFKKVPheh4/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups "jOOQ 
User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to