hibernate/hibernate-orm · error · TransactionException
Cannot roll back transaction in current status [
Error message
Cannot roll back transaction in current status [
What it means
rollback() no-ops only for ROLLED_BACK and NOT_ACTIVE; for everything else it checks TransactionStatus.canRollback(), which is true only for ACTIVE, MARKED_ROLLBACK, and FAILED_COMMIT. Statuses such as COMMITTED, COMMITTING, or ROLLING_BACK cannot be rolled back, so a TransactionException names the offending status.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionImpl.java:124
}
else {
return transactionDriverControl;
}
}
@Override
public void rollback() {
if ( !isActive() && jpaCompliance ) {
throw new IllegalStateException( "rollback() called on inactive transaction (in JPA compliant mode)" );
}
final var status = getStatus();
if ( status == TransactionStatus.ROLLED_BACK || status == TransactionStatus.NOT_ACTIVE ) {
// allow rollback() on completed transaction as noop
CORE_LOGGER.rollbackCalledOnInactiveTransaction();
}
else if ( !status.canRollback() ) {
throw new TransactionException( "Cannot roll back transaction in current status [" + status.name() + "]" );
}
else if ( status != TransactionStatus.FAILED_COMMIT || allowFailedCommitToPhysicallyRollback() ) {
CORE_LOGGER.rollingBackTransaction();
internalGetTransactionDriverControl().rollback();
}
}
@Override
public boolean isActive() {
if ( transactionDriverControl == null ) {
if ( session.isOpen() ) {
transactionDriverControl =
transactionCoordinator.getTransactionDriverControl();
}
else {
return false;
}
}View on GitHub (pinned to fad1729dce)
Solutions
- Check the status before rolling back: if (tx.getStatus().canRollback()) tx.rollback();
- Do not touch the transaction after commit() returns — start a new transaction if compensating work is needed
- Order cleanup logic so commit is the final step and later failures cannot reach the transaction object
Example fix
// before
try {
tx.commit();
notifyListeners();
} catch (RuntimeException e) {
tx.rollback(); // status COMMITTED -> TransactionException
}
// after
try {
tx.commit();
} catch (RuntimeException e) {
if (tx.getStatus().canRollback()) {
tx.rollback();
}
throw e;
}
notifyListeners(); Defensive patterns
Strategy: validation
Validate before calling
org.hibernate.resource.transaction.spi.TransactionStatus st = tx.getStatus();
if (st == org.hibernate.resource.transaction.spi.TransactionStatus.ROLLED_BACK
|| st == org.hibernate.resource.transaction.spi.TransactionStatus.NOT_ACTIVE) {
// Hibernate no-ops these; nothing to do
} else if (st.canRollback()) {
tx.rollback();
} else {
log.warn("Cannot roll back transaction in status {}", st);
} Try / catch
try {
tx.rollback();
} catch (TransactionException e) {
if (String.valueOf(e.getMessage()).startsWith("Cannot roll back transaction")) {
// commit already finished or is in flight — nothing to undo
log.warn("Rollback skipped: {}", e.getMessage());
} else {
throw e;
}
} Prevention
- Check tx.getStatus().canRollback() before rolling back in shared error handlers
- Never call rollback after a successful commit — use a compensating transaction instead
- Keep commit as the final statement of the transactional scope
When it happens
Trigger: tx.rollback() after tx.commit() succeeded (status COMMITTED); rollback attempted while a commit is in progress (COMMITTING) or while another rollback is already running (ROLLING_BACK); synchronization callbacks trying to roll back mid-commit.
Common situations: Catch blocks that run after a successful commit and roll back 'to be safe'; post-commit listeners throwing exceptions that trigger a generic rollback path; concurrent error handling around a completing transaction.
Related errors
- rollback() called on inactive transaction (in JPA compliant
- Unable to rollback against JDBC Connection
- Newer version [" + latestVersion + "] of entity [" + infoStr
- Unable to locate current JTA transaction
- Current transaction is not in progress
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/c2b9532924b904fa.
Report an issue: GitHub.