Incomplete SQL transaction in create()

Description

When create() exits in the conditional block

if (returnedExpiration == null || System.currentTimeMillis() < returnedExpiration) { log.debug("Duplicate record '{}' in context '{}'", key, context); return false; }

the SQL connection is returned to the pool with the transaction still open. The next time this connection is retrieved from the pool by the constructor of ConnectionWithLock, the call to setTransactionIsolation() will fail with org.postgresql.util.PSQLException: Cannot change transaction isolation level in the middle of a transaction. if the PostgreSQL JDBC driver is used.

Environment

None

Activity

Rod WiddowsonMarch 24, 2025 at 10:28 AM

Reopen to set fix in

Rod WiddowsonSeptember 24, 2024 at 7:19 PM

You might want to either rebuild or try with tomorrows snapshot. Thanks for the report

Rod WiddowsonSeptember 24, 2024 at 7:15 PM
Edited

>You mean by turning off auto-commit? Might work, but this is definitely pushing into crazy territory.

Na simpler than that. Remove all the spurious rollbacks that I added (belt & suspenders) with the last.

I’ve also added some asserts to the connection to make sure that we do exactly one of autoCommit/commit/rollback and that works nicely because tts not Db depdendant

It also speaks to your “call commit” suggestion because that's exactly what auto commit does: “Do a commit/stop transaction/start transaction after every operation.”

The asserts worked (I found a bug) so I am about to push

Scott CantorSeptember 24, 2024 at 7:12 PM

Unless you mean my suggestion about just turning off auto-commit…then yeah, makes sense to rollback if it’s not already been committed, but I’m not sure how you could tell, maybe a flag on the wrapper object…

Scott CantorSeptember 24, 2024 at 7:11 PM

I’ll review and change. I’m actually almost tempted to make it automatic (so if an auto-commit connection is closed without being committed we roll it back)

You mean by turning off auto-commit? Might work, but this is definitely pushing into crazy territory.

I’m really uncomfortable doing this its like saying to the App “No, nothing happened” and saying to the database “Write it all”. This is fine for as long as we know we haven’t written anything and I agree its unlilky that we will change the code path, but its precisely that unlikeliness which makes it risky

These aren’t generic code paths though, it’s in the logic implementing the reads and writes, so we know exactly what we did or didn’t do, and nothing we do in this code ever needs to be rolled back. If we were writing some general database layer, probably different story.

We probably need to review all this in the persistent ID code and the data connector BTW.

Completed

Details

Affects versions

Fix versions

Assignee

Reporter

Created September 16, 2024 at 9:30 AM
Updated March 24, 2025 at 10:29 AM
Resolved March 24, 2025 at 10:29 AM

Flag notifications