hibernate/hibernate-orm · error · TransactionException

JTA TransactionManager.commit() failed

Error message

JTA TransactionManager.commit() failed

What it means

The commit path of the TransactionManager-based JTA adapter: TransactionManager.commit() threw and is wrapped in this TransactionException, surfaced from Transaction.commit(). Frequent wrapped causes are RollbackException (the transaction was already marked rollback-only, often by a swallowed application error), HeuristicMixedException/HeuristicRollbackException (XA resources disagreed), SystemException, or IllegalStateException (no transaction / wrong thread). Note the initiator flag is cleared before commit, so retries of commit() will not reach the TM again.

Source

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

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

	@Override
	public void commit() {
		try {
			if ( initiator ) {
				initiator = false;
				JTA_LOGGER.callingTransactionManagerCommit();
				transactionManager.commit();
				JTA_LOGGER.calledTransactionManagerCommit();
			}
			else {
				JTA_LOGGER.skippingTransactionManagerCommit();
			}
		}
		catch (Exception e) {
			throw new TransactionException( "JTA TransactionManager.commit() failed", e );
		}
	}

	@Override
	public void rollback() {
		try {
			if ( initiator ) {
				initiator = false;
				JTA_LOGGER.callingTransactionManagerRollback();
				transactionManager.rollback();
				JTA_LOGGER.calledTransactionManagerRollback();
			}
			else {
				markRollbackOnly();
			}
		}
		catch (Exception e) {
			throw new TransactionException( "JTA TransactionManager.rollback() failed", e );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Find the earlier 'marked as rollback-only' warning in the logs and fix that root cause - the commit error is only the symptom
  2. Stop swallowing exceptions inside the transaction; let it roll back with the original error
  3. For heuristic causes, inspect and resolve the TM transaction store (e.g., Narayana object store) and resource-manager logs
  4. Ensure commit runs on the thread that began the transaction

Example fix

// before
try {
    em.persist(order);
}
catch (RuntimeException e) {
    log.warn("ignoring", e); // JTA tx is now rollback-only
}
// ... later commit -> TransactionException: JTA TransactionManager.commit() failed

// after
em.persist(order); // let exceptions propagate; the tx rolls back with the real error
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 + " (rollback-only?)");
}

Try / catch

catch (TransactionException e) {
    Throwable c = e.getCause();
    if ( c instanceof RollbackException ) {
        // tx was marked rollback-only: find the ORIGINAL failure earlier in the logs
    }
    else if ( c instanceof HeuristicMixedException || c instanceof HeuristicRollbackException ) {
        // resolve the TM transaction store / resource manager logs
    }
    // do not retry commit(): the initiator flag was already cleared
}

Prevention

When it happens

Trigger: tx.commit() after something marked the JTA transaction rollback-only (a caught-and-ignored constraint violation, a failing beforeCompletion Synchronization, an XA resource voting rollback); an XA heuristic outcome at commit; commit from a thread that does not own the transaction.

Common situations: Catching a PersistenceException/HibernateException inside a business method but still committing; XA participants timing out; leftover heuristic entries after a crashed resource manager.

Related errors


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