{"record":{"id":"acc342a499c29491","repo":"hibernate/hibernate-orm","slug":"resource-local-transaction-already-active","errorCode":null,"errorMessage":"Resource-local transaction already active","messagePattern":"Resource-local transaction already active","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionImpl.java","lineNumber":74,"sourceCode":"\t}\n\n\t@Override\n\tpublic void begin() {\n\t\tif ( !session.isOpen() ) {\n\t\t\tthrow new IllegalStateException( \"Cannot begin Transaction on closed Session/EntityManager\" );\n\t\t}\n\n\t\tif ( transactionDriverControl == null ) {\n\t\t\ttransactionDriverControl =\n\t\t\t\t\ttransactionCoordinator.getTransactionDriverControl();\n\t\t}\n\n\t\tif ( isActive() ) {\n\t\t\tif ( jpaCompliance ) {\n\t\t\t\tthrow new IllegalStateException( \"Transaction already active (in JPA compliant mode)\" );\n\t\t\t}\n\t\t\telse if ( !transactionCoordinator.getTransactionCoordinatorBuilder().isJta() ) {\n\t\t\t\tthrow new IllegalStateException( \"Resource-local transaction already active\" );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tCORE_LOGGER.beginningTransaction();\n\t\t\ttransactionDriverControl.begin();\n\t\t}\n\t}\n\n\t@Override\n\tpublic void commit() {\n\t\t// allow MARKED_ROLLBACK to propagate through to transactionDriverControl\n\t\tif ( !isActive() ) {\n\t\t\t// we have a transaction that is inactive and has not been marked for rollback only\n\t\t\tthrow new IllegalStateException( \"Transaction not successfully started\" );\n\t\t}\n\t\telse {\n\t\t\tCORE_LOGGER.committingTransaction();\n\t\t\ttry {","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionImpl.java#L56-L92","documentation":"The non-JPA branch of TransactionImpl.begin(): when a transaction is already active, jpaCompliance is off, and the coordinator is not JTA (resource-local JDBC), Hibernate still refuses a second begin() with IllegalStateException. Native mode is only slightly more lenient than JPA mode — it never silently joins an existing resource-local transaction.","triggerScenarios":"session.beginTransaction() called twice in native Hibernate mode with a resource-local (JDBC) transaction coordinator and no commit/rollback between the calls; the second call sees isActive() and a non-JTA coordinator and throws.","commonSituations":"Defensive begin() calls in utility/service methods that call each other; batch loops that begin per iteration when a commit path is skipped on exception; migration from JTA to resource-local datasources where join semantics were expected.","solutions":["Reuse the current transaction: keep the Transaction from the first begin() or check session.getTransaction().isActive() before calling begin() again","Restructure nested calls so exactly one layer owns begin/commit (template-method or try-with-resources pattern)","Ensure exception paths still commit or roll back, so no active transaction leaks into the next begin()"],"exampleFix":"// before\nTransaction tx = session.beginTransaction();\nprocessBatchPart1();\nTransaction tx2 = session.beginTransaction(); // resource-local -> IllegalStateException\n\n// after\nTransaction tx = session.getTransaction();\nif (!tx.isActive()) {\n    tx = session.beginTransaction();\n}\nprocessBatchPart1();","handlingStrategy":"validation","validationCode":"Transaction tx = session.getTransaction();\nif (!tx.isActive()) {\n    tx = session.beginTransaction();\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["One layer owns transaction demarcation; pass the Transaction down instead of re-beginning","Use session.getTransaction() to detect an in-progress transaction before beginning","Guarantee commit/rollback in finally so no active transaction leaks"],"tags":["hibernate","transaction","resource-local","double-begin","native-api"],"backgroundTag":"transaction-already-active","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}