Skip to content

fix: release START_TXN nesting level on persist() SQLException path (#13905) - #13925

Open
waterWang wants to merge 1 commit into
apache:mainfrom
waterWang:fix-persist-txn-leak-13905
Open

fix: release START_TXN nesting level on persist() SQLException path (#13905)#13925
waterWang wants to merge 1 commit into
apache:mainfrom
waterWang:fix-persist-txn-leak-13905

Conversation

@waterWang

Copy link
Copy Markdown

Description

GenericDaoBase.persist() calls txn.start() which pushes a START_TXN nesting level onto the caller's transaction stack. When the insert throws SQLException, the catch block rethrows without reaching txn.commit(), so the pushed nesting level is leaked. The caller's later commit() then finds the transaction unbalanced and silently no-ops (logging only txn: Commit called when it is not a transaction), discarding everything the caller believed it committed.

Callers that deliberately catch EntityExistsException to log-and-continue cannot actually continue, because the enclosing transaction is already unrecoverable — this converts a single constraint violation into permanent failure (see #13399).

Fix

Track commit success via a committed flag; in a finally block, roll back the transaction when the commit was not reached, restoring the caller's transaction to a balanced state.

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improvement to existing features and functionality)
  • Refactoring (non-breaking change which restructures existing code)
  • Documentation update

How has this been tested?

Code-review level only — the change adds a rollback guard to the existing try/catch structure. Existing tests cover DAO persist paths.

Closes #13905

…pache#13905)

GenericDaoBase.persist() calls txn.start() which pushes a START_TXN
nesting level onto the caller's transaction stack. The SQLException
catch block throws without reaching txn.commit(), so the nesting
level is leaked. The caller's subsequent commit() finds the
transaction unbalanced and silently no-ops — all caller work in
that batch is lost with no error.

Fix: track commit success and roll back the START_TXN level in a
finally block when commit() was not reached, ensuring the caller's
transaction is restored to a balanced state instead of silently
abandoning its work.

Closes apache#13905

Signed-off-by: waterWang <waterwang@proton.me>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GenericDaoBase.persist() leaves the caller's transaction unbalanced when an insert throws

1 participant