hibernate/hibernate-orm · error · TransactionException

JTA UserTransaction.commit() failed

Error message

JTA UserTransaction.commit() failed

What it means

UserTransaction.commit() threw and is wrapped in this TransactionException, surfaced from Transaction.commit() on a coordinator that drives UserTransaction. Typical wrapped causes: RollbackException (the transaction was marked rollback-only earlier, frequently by a swallowed application error), HeuristicMixedException/HeuristicRollbackException, SystemException, SecurityException, or IllegalStateException. As with the TransactionManager variant, the initiator flag is cleared before commit, so the commit is not retried.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/JtaTransactionAdapterUserTransactionImpl.java:64

			throw new TransactionException( "JTA UserTransaction.begin() failed", e );
		}
	}

	@Override
	public void commit() {
		try {
			if ( initiator ) {
				initiator = false;
				JTA_LOGGER.callingUserTransactionCommit();
				userTransaction.commit();
				JTA_LOGGER.calledUserTransactionCommit();
			}
			else {
				JTA_LOGGER.skippingTransactionManagerCommit();
			}
		}
		catch (Exception e) {
			throw new TransactionException( "JTA UserTransaction.commit() failed", e );
		}
	}

	@Override
	public void rollback() {
		try {
			if ( initiator ) {
				initiator = false;
				JTA_LOGGER.callingUserTransactionRollback();
				userTransaction.rollback();
				JTA_LOGGER.calledUserTransactionRollback();
			}
			else {
				markRollbackOnly();
			}
		}
		catch (Exception e) {
			throw new TransactionException( "JTA UserTransaction.rollback() failed", e );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Locate the earlier rollback-only cause in the logs and fix it; the commit failure is downstream of it
  2. Let failures propagate and roll back instead of committing anyway
  3. Resolve TM heuristic entries when the cause is a Heuristic*Exception
  4. Ensure the calling context is permitted to commit the UserTransaction
Defensive patterns

Strategy: try-catch

Validate before calling

// Know the tx is committable before committing
TransactionStatus st = session.getTransaction().getStatus();
if ( st != TransactionStatus.ACTIVE ) {
    throw new IllegalStateException("Cannot commit: tx status " + st);
}

Try / catch

catch (TransactionException e) {
    Throwable c = e.getCause();
    if ( c instanceof RollbackException ) {
        // find the original rollback-only cause earlier in the logs
    }
    else if ( c instanceof SecurityException ) {
        // the calling context is not allowed to commit the UserTransaction
    }
    // never blind-retry commit(): initiator was already cleared
}

Prevention

When it happens

Trigger: tx.commit() after the JTA transaction was marked rollback-only; an XA heuristic outcome at commit; commit called with no active transaction, from a disallowed security context (SecurityException), or the wrong thread.

Common situations: Ignoring a persistence exception and still committing in bean-managed transactions; a UT/TM timeout completing the transaction before the commit; security restrictions on BMT commit.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/c5d685c84e668d5f. Report an issue: GitHub.