Unexpected rollback on closing handle

340 views
Skip to first unread message

Massimo Redaelli

unread,
Aug 18, 2017, 6:10:06 AM8/18/17
to jDBI

(Sorry, I posted the same thing on github, but probably that's not the right place to ask, so I closed it and came here.)


I'm trying to port some code from v2 to v3.

I basically do

        final String dimension = Jdbi.create(new UXConnectionFactory()).withHandle(h ->
            h.createQuery("select DIMENSIE from ordrgl where syscode = :syscode")
                .bind("syscode", pos.getPrimaryKey())
                .mapTo(String.class)
                .findFirst().orElse(""));

where UXConnectionFactory returns a managed connection from my Wildfly instance.


The equivalent code with a try-resource on Handle in v2 gave no problem.


Now I get:

org.jdbi.v3.core.transaction.TransactionException: Rollback called, this runtime exception thrown to halt the transaction
at org.jdbi.v3.core.transaction.CMTTransactionHandler.rollback(CMTTransactionHandler.java:53)
    at org.jdbi.v3.core.Handle.rollback(Handle.java:288)
    at org.jdbi.v3.core.Handle.close(Handle.java:123)
    at org.jdbi.v3.core.Jdbi.withHandle(Jdbi.java:341)

so it seems I'm doing something stupid, but I have no idea what. I tried using a CMTTransactionHandler, but I only a different exception, a bit earlier.

Help ^^

Steven Schlansker

unread,
Aug 18, 2017, 12:27:51 PM8/18/17
to jd...@googlegroups.com
I don't actually know what the CMTTransactionHandler is useful for honestly. The code unconditionally
throws on rollback.

What exception do you get with the default transaction handler?
> --
> You received this message because you are subscribed to the Google Groups "jDBI" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to jdbi+uns...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

signature.asc

Massimo Redaelli

unread,
Aug 21, 2017, 3:51:37 AM8/21/17
to jDBI
I get this:

 org.jdbi.v3.core.transaction.TransactionException: Failed to rollback transaction
at org.jdbi.v3.core.transaction.LocalTransactionHandler.rollback(LocalTransactionHandler.java:73)
at org.jdbi.v3.core.Handle.rollback(Handle.java:288)
at org.jdbi.v3.core.Handle.close(Handle.java:123)
[...]
 Caused by: java.sql.SQLException: IJ031021: You cannot rollback during a managed transaction
at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.jdbcRollback(BaseWrapperManagedConnection.java:1101)
at org.jboss.jca.adapters.jdbc.WrappedConnection.rollback(WrappedConnection.java:863)
at org.jdbi.v3.core.transaction.LocalTransactionHandler.rollback(LocalTransactionHandler.java:70)


The "problem" is in Handle.close(), in these lines:

if (!this.closed) {
boolean wasInTransaction = this.isInTransaction();
if (wasInTransaction) {
this.rollback();
}

I'm not sure what the logic behind that is, or why there should be a forced rollback at that point.

Thanks

M.

Massimo Redaelli

unread,
Aug 21, 2017, 4:37:04 AM8/21/17
to jDBI
This is the commit that introduced that behaviour:

https://github.com/jdbi/jdbi/commit/932f11049a0f26dce577cc182538b7a6c530c9d7

The isInTransaction() method returns !handle.getConnection().getAutoCommit(); and since the getAutoCommit() for the connection I get in my UXConnectionFactory is set to false, it does think it is in a transaction.
Which is true, but still the transaction is managed by the Wildfly.

I could of course change the connection pool to non-managed, but I don't have the rights to do that.

I could try to write a simple TransactionManager that would work in this case, returning false in isInTransaction(), but that would be semantically wrong. What do you think?

M.

Massimo Redaelli

unread,
Aug 21, 2017, 5:51:42 AM8/21/17
to jDBI
I forked the beta3-snapshot and created a branch with a possible fix for this issue (assuming it is an issue ^^ ).

It's here:


Let me know .)

M.

Steven Schlansker

unread,
Aug 23, 2017, 12:54:43 PM8/23/17
to jd...@googlegroups.com
Hi Massimo,

I have to admit, I don't really understand how the CMT transaction handler is supposed
to work -- nor what the semantics of a "managed" transaction are. Can you explain a little bit
about what exact issue this fixes? What database product(s) are you using?

If you're looking for transactions to be managed externally, do you just want a "nop" transaction
handler that simply does nothing and lets you handle it?
signature.asc

Massimo Redaelli

unread,
Aug 24, 2017, 4:04:13 AM8/24/17
to jDBI
Hi!

To be honest, I'm not very familiar with it myself, although this might be a good description of the semantics: http://what-when-how.com/enterprise-javabeans-3/container-managed-transactions-ejb-3/

I'm not even sure my environment is actually using CMT - it's just that the idea behind seems similar, so I thought of reusing that class :P
I don't have many details on the architecture of the application I'm working on: I only get an API and deploy OSGi modules to extend it. But it's a WildFly 10 application, if that helps ^^

All I know is that I am given a Connection object for which autocommit() is false, but which I cannot rollback() or commit() myself (lest I get an exception). 
As such, it seems to me jDBI as is now cannot work.

And yes, another, functionally equivalent option would be to have a nop transaction handler. But then I don't think that the current CMT transaction handler makes much sense (it would throw the rollback exception anyway, at least in my case), and, more importantly, semantically to call a nop commit is at best misleading.

M.

Matthew Hall

unread,
Sep 17, 2017, 6:47:38 PM9/17/17
to jd...@googlegroups.com
If I've understood this thread correctly, I think we have confirmation of the problem described in https://github.com/jdbi/jdbi/issues/881.

Jdbi 3 introduced that behavior to help catch invalid usage--e.g. opening a transaction without explicitly commit or rolling back.

What we failed to do, is check whether a transaction was already open on the connection when the handle was allocated.

I'll move the bug to pre-release v3 and we'll get a fix in for the next beta.

-Matthew





--
You received this message because you are subscribed to the Google Groups "jDBI" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jdbi+unsubscribe@googlegroups.com.

Matthew Hall

unread,
Oct 4, 2017, 9:51:29 PM10/4/17
to jDBI
I've opened a PR to address this issue in https://github.com/jdbi/jdbi/pull/904.

To anybody affected by this bug, please pull that branch, build it and try out your app with it. Leave a comment on the PR and let us know if that fixes the problem for you.
Reply all
Reply to author
Forward
0 new messages