{"record":{"id":"93706bf4ccfca2ac","repo":"hibernate/hibernate-orm","slug":"jta-transactionmanager-commit-failed","errorCode":null,"errorMessage":"JTA TransactionManager.commit() failed","messagePattern":"JTA TransactionManager\\.commit\\(\\) failed","errorType":"exception","errorClass":"TransactionException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/JtaTransactionAdapterTransactionManagerImpl.java","lineNumber":63,"sourceCode":"\t\t\tthrow new TransactionException( \"JTA TransactionManager.begin() failed\", e );\n\t\t}\n\t}\n\n\t@Override\n\tpublic void commit() {\n\t\ttry {\n\t\t\tif ( initiator ) {\n\t\t\t\tinitiator = false;\n\t\t\t\tJTA_LOGGER.callingTransactionManagerCommit();\n\t\t\t\ttransactionManager.commit();\n\t\t\t\tJTA_LOGGER.calledTransactionManagerCommit();\n\t\t\t}\n\t\t\telse {\n\t\t\t\tJTA_LOGGER.skippingTransactionManagerCommit();\n\t\t\t}\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new TransactionException( \"JTA TransactionManager.commit() failed\", e );\n\t\t}\n\t}\n\n\t@Override\n\tpublic void rollback() {\n\t\ttry {\n\t\t\tif ( initiator ) {\n\t\t\t\tinitiator = false;\n\t\t\t\tJTA_LOGGER.callingTransactionManagerRollback();\n\t\t\t\ttransactionManager.rollback();\n\t\t\t\tJTA_LOGGER.calledTransactionManagerRollback();\n\t\t\t}\n\t\t\telse {\n\t\t\t\tmarkRollbackOnly();\n\t\t\t}\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new TransactionException( \"JTA TransactionManager.rollback() failed\", e );","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/JtaTransactionAdapterTransactionManagerImpl.java#L45-L81","documentation":"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.","triggerScenarios":"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.","commonSituations":"Catching a PersistenceException/HibernateException inside a business method but still committing; XA participants timing out; leftover heuristic entries after a crashed resource manager.","solutions":["Find the earlier 'marked as rollback-only' warning in the logs and fix that root cause - the commit error is only the symptom","Stop swallowing exceptions inside the transaction; let it roll back with the original error","For heuristic causes, inspect and resolve the TM transaction store (e.g., Narayana object store) and resource-manager logs","Ensure commit runs on the thread that began the transaction"],"exampleFix":"// before\ntry {\n    em.persist(order);\n}\ncatch (RuntimeException e) {\n    log.warn(\"ignoring\", e); // JTA tx is now rollback-only\n}\n// ... later commit -> TransactionException: JTA TransactionManager.commit() failed\n\n// after\nem.persist(order); // let exceptions propagate; the tx rolls back with the real error","handlingStrategy":"try-catch","validationCode":"// Know the tx is committable before committing\nTransactionStatus st = session.getTransaction().getStatus();\nif ( st != TransactionStatus.ACTIVE ) {\n    throw new IllegalStateException(\"Cannot commit: tx status \" + st + \" (rollback-only?)\");\n}","typeGuard":null,"tryCatchPattern":"catch (TransactionException e) {\n    Throwable c = e.getCause();\n    if ( c instanceof RollbackException ) {\n        // tx was marked rollback-only: find the ORIGINAL failure earlier in the logs\n    }\n    else if ( c instanceof HeuristicMixedException || c instanceof HeuristicRollbackException ) {\n        // resolve the TM transaction store / resource manager logs\n    }\n    // do not retry commit(): the initiator flag was already cleared\n}","preventionTips":["Never swallow persistence exceptions inside an active transaction","Log beforeCompletion Synchronization failures loudly so rollback-only causes stay traceable","Monitor XA resource health to avoid heuristic outcomes"],"tags":["jta","transactions","hibernate","commit","rollback-only","xa-heuristics"],"backgroundTag":"transaction-commit-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}