{"record":{"id":"5f7ec86dff91725c","repo":"flowable/flowable-engine","slug":"systemexception-while-getting-transaction","errorCode":null,"errorMessage":"SystemException while getting transaction ","messagePattern":"SystemException while getting transaction ","errorType":"exception","errorClass":"org.flowable.common.engine.api.FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/cfg/jta/JtaTransactionContext.java","lineNumber":66,"sourceCode":"        // managed transaction, mark rollback-only if not done so already.\n        try {\n            Transaction transaction = getTransaction();\n            int status = transaction.getStatus();\n            if (status != Status.STATUS_NO_TRANSACTION && status != Status.STATUS_ROLLEDBACK) {\n                transaction.setRollbackOnly();\n            }\n        } catch (IllegalStateException e) {\n            throw new FlowableException(\"Unexpected IllegalStateException while marking transaction rollback only\", e);\n        } catch (SystemException e) {\n            throw new FlowableException(\"SystemException while marking transaction rollback only\", e);\n        }\n    }\n\n    protected Transaction getTransaction() {\n        try {\n            return transactionManager.getTransaction();\n        } catch (SystemException e) {\n            throw new FlowableException(\"SystemException while getting transaction \", e);\n        }\n    }\n\n    @Override\n    public void addTransactionListener(TransactionState transactionState, final TransactionListener transactionListener) {\n\n        Transaction transaction = getTransaction();\n        CommandContext commandContext = Context.getCommandContext();\n        try {\n            transaction.registerSynchronization(new TransactionStateSynchronization(transactionState, transactionListener, commandContext));\n        } catch (IllegalStateException e) {\n            throw new FlowableException(\"IllegalStateException while registering synchronization \", e);\n        } catch (RollbackException e) {\n            throw new FlowableException(\"RollbackException while registering synchronization \", e);\n        } catch (SystemException e) {\n            throw new FlowableException(\"SystemException while registering synchronization \", e);\n        }\n    }","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/cfg/jta/JtaTransactionContext.java#L48-L84","documentation":"In JtaTransactionContext, getTransaction() calls TransactionManager.getTransaction() and translates any javax.transaction.SystemException into this FlowableException. It means the JTA transaction manager failed while resolving the transaction associated with the current thread, so Flowable cannot proceed with transactional work.","triggerScenarios":"Any JtaTransactionContext operation (e.g. rollback() or addTransactionListener() via getTransaction()) when TransactionManager.getTransaction() throws SystemException — TM internal failure, thread without proper TM association in an exotic setup.","commonSituations":"Improperly bootstrapped TransactionManager (e.g. standalone JTA like Atomikos/Narayana misconfigured); calling Flowable APIs from threads not managed by the TM; app-server TM service failures.","solutions":["Inspect the wrapped cause for the transaction manager's failure details.","Ensure Flowable commands run on threads managed by the JTA transaction manager (not raw executor threads without transaction context).","Verify the TransactionManager bean/JNDI wiring passed into JtaTransactionContextFactory is the live container TM.","If running standalone JTA (Bitronix/Atomikos/Narayana), confirm the TM is started before the engine executes commands.","Retry the operation; persistent SystemException may require restarting the TM/service."],"exampleFix":"// before: engine invoked from unmanaged thread\nnew Thread(() -> engine.getTaskService().complete(taskId)).start();\n// after: execute within a managed transaction on the caller thread\nuserTransaction.begin();\ntry { engine.getTaskService().complete(taskId); userTransaction.commit(); }\ncatch (Exception e) { userTransaction.rollback(); throw e; }","handlingStrategy":"try-catch","validationCode":"try {\n  Transaction tx = tm.getTransaction();\n  if (tx == null) throw new IllegalStateException(\"No JTA transaction on this thread\");\n} catch (SystemException e) {\n  throw new IllegalStateException(\"TM failed to resolve transaction\", e);\n}","typeGuard":"boolean tmIsHealthy(TransactionManager tm) {\n  try { tm.getTransaction(); return true; } catch (SystemException e) { return false; }\n}","tryCatchPattern":"try {\n  engine.getRuntimeService().startProcessInstanceByKey(\"p\");\n} catch (FlowableException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"SystemException while getting transaction\")) {\n    // TM broken: escalate / retry after TM recovery\n  } else throw e;\n}","preventionTips":["Start the standalone TM (Atomikos/Narayana/Bitronix) before executing engine commands.","Only invoke engine APIs from threads with proper transaction context.","Validate TM bootstrap configuration in an integration test.","Retry transient failures; restart the TM if the service is persistently degraded."],"tags":["jta","transaction","system-exception","flowable"],"backgroundTag":"upstream-api-error","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}