{"record":{"id":"fae3560f739f8504","repo":"quarkusio/quarkus","slug":"transaction-already-active-fae356","errorCode":null,"errorMessage":"Transaction already active","messagePattern":"Transaction already active","errorType":"exception","errorClass":"QuarkusTransactionException","httpStatus":null,"severity":"error","filePath":"extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/RequestScopedTransaction.java","lineNumber":57,"sourceCode":"            TransactionManager transactionManager, TransactionManagerConfiguration transactionManagerConfiguration) {\n        this.userTransaction = userTransaction;\n        this.transactionManager = transactionManager;\n        this.transactionManagerConfiguration = transactionManagerConfiguration;\n    }\n\n    public RequestScopedTransaction() {\n        //for proxiability\n        this.userTransaction = null;\n        this.transactionManagerConfiguration = null;\n        this.transactionManager = null;\n    }\n\n    void begin(BeginOptions options) {\n        int timeout = options != null ? options.timeout : 0;\n        boolean commitOnRequestScopeEnd = options != null && options.commitOnRequestScopeEnd;\n        try {\n            if (userTransaction.getStatus() != Status.STATUS_NO_TRANSACTION) {\n                throw new QuarkusTransactionException(\"Transaction already active\");\n\n            }\n            this.autoCommit = commitOnRequestScopeEnd;\n            if (timeout > 0) {\n                userTransaction.setTransactionTimeout(timeout);\n            }\n            userTransaction.begin();\n            createdTransaction = transactionManager.getTransaction();\n        } catch (NotSupportedException | SystemException e) {\n            throw new QuarkusTransactionException(e);\n        } finally {\n            if (timeout > 0) {\n                try {\n                    userTransaction.setTransactionTimeout(\n                            (int) transactionManagerConfiguration.defaultTransactionTimeout().toSeconds());\n                } catch (SystemException e) {\n                    throw new QuarkusTransactionException(e);\n                }","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/RequestScopedTransaction.java#L39-L75","documentation":"RequestScopedTransaction.begin starts the request-scoped user transaction and throws QuarkusTransactionException('Transaction already active') if the underlying UserTransaction's status is not STATUS_NO_TRANSACTION, i.e. a transaction is already in progress on the thread. This guards the commit-on-request-scope-end contract against double begin.","triggerScenarios":"The request-scoped transaction bean's begin() is invoked twice in one request scope, or an external transaction (manual UserTransaction.begin, Narayana timeout recovery, or another component) was already started before the request-scoped transaction initializes.","commonSituations":"Mixing programmatic QuarkusTransaction.begin with the automatic request-scoped transaction management; a leaked/unclosed transaction from an earlier request handled by the same worker thread; nested service calls each triggering begin.","solutions":["Do not call QuarkusTransaction.begin when a transaction is already active — check QuarkusTransaction.isActive() first","Ensure previous transactions are committed/rolled back (look for missing commit/rollback in error paths)","Avoid mixing manual UserTransaction usage with request-scoped transaction management","If a stale transaction leaks from earlier work, roll it back before beginning a new one"],"exampleFix":"// before\nQuarkusTransaction.begin(); // may throw if already active\n// after\nif (!QuarkusTransaction.isActive()) {\n    QuarkusTransaction.begin();\n}","handlingStrategy":"try-catch","validationCode":"try {\n    int status = userTransaction.getStatus();\n    if (status != Status.STATUS_NO_TRANSACTION) {\n        throw new IllegalStateException(\"Cannot begin: transaction status=\" + status);\n    }\n} catch (SystemException e) { /* handle */ }","typeGuard":null,"tryCatchPattern":"try {\n    QuarkusTransaction.begin();\n} catch (QuarkusTransactionException e) {\n    if (e.getMessage().contains(\"Transaction already active\")) {\n        QuarkusTransaction.rollback(); // or join existing tx instead\n        QuarkusTransaction.begin();\n    } else throw e;\n}","preventionTips":["Check QuarkusTransaction.isActive() before beginning","Always commit/rollback in finally blocks to avoid leaked transactions on worker threads","Do not mix manual UserTransaction calls with request-scoped transaction management","Watch for Narayana recovery/timeout reapers leaving transactions active"],"tags":["narayana","transaction","request-scope","illegal-state"],"backgroundTag":"transaction-already-active","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}