flowable/flowable-engine · error · org.flowable.common.engine.api.FlowableException
SystemException while getting transaction
Error message
SystemException while getting transaction
What it means
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.
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.
Example fix
// before: engine invoked from unmanaged thread
new Thread(() -> engine.getTaskService().complete(taskId)).start();
// after: execute within a managed transaction on the caller thread
userTransaction.begin();
try { engine.getTaskService().complete(taskId); userTransaction.commit(); }
catch (Exception e) { userTransaction.rollback(); throw e; } Defensive patterns
Strategy: try-catch
Validate before calling
try {
Transaction tx = tm.getTransaction();
if (tx == null) throw new IllegalStateException("No JTA transaction on this thread");
} catch (SystemException e) {
throw new IllegalStateException("TM failed to resolve transaction", e);
} Type guard
boolean tmIsHealthy(TransactionManager tm) {
try { tm.getTransaction(); return true; } catch (SystemException e) { return false; }
} Try / catch
try {
engine.getRuntimeService().startProcessInstanceByKey("p");
} catch (FlowableException e) {
if (e.getMessage() != null && e.getMessage().contains("SystemException while getting transaction")) {
// TM broken: escalate / retry after TM recovery
} else throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- SystemException while marking transaction rollback only
- IllegalStateException while registering synchronization
- RollbackException while registering synchronization
- SystemException while getting transaction
- SystemException while marking transaction rollback only
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/5f7ec86dff91725c.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/cfg/jta/JtaTransactionContext.java:66
// managed transaction, mark rollback-only if not done so already.
try {
Transaction transaction = getTransaction();
int status = transaction.getStatus();
if (status != Status.STATUS_NO_TRANSACTION && status != Status.STATUS_ROLLEDBACK) {
transaction.setRollbackOnly();
}
} catch (IllegalStateException e) {
throw new FlowableException("Unexpected IllegalStateException while marking transaction rollback only", e);
} catch (SystemException e) {
throw new FlowableException("SystemException while marking transaction rollback only", e);
}
}
protected Transaction getTransaction() {
try {
return transactionManager.getTransaction();
} catch (SystemException e) {
throw new FlowableException("SystemException while getting transaction ", e);
}
}
@Override
public void addTransactionListener(TransactionState transactionState, final TransactionListener transactionListener) {
Transaction transaction = getTransaction();
CommandContext commandContext = Context.getCommandContext();
try {
transaction.registerSynchronization(new TransactionStateSynchronization(transactionState, transactionListener, commandContext));
} catch (IllegalStateException e) {
throw new FlowableException("IllegalStateException while registering synchronization ", e);
} catch (RollbackException e) {
throw new FlowableException("RollbackException while registering synchronization ", e);
} catch (SystemException e) {
throw new FlowableException("SystemException while registering synchronization ", e);
}
}View on GitHub (pinned to d6d39ce1c6)