pentaho/pentaho-kettle · critical · KettleDatabaseException
Unable to commit connection after having inserted rows.
Error message
Unable to commit connection after having inserted rows.
What it means
Kettle wraps any SQLException that occurs while committing a connection after a batch of inserts (in Database.commitInsert / the insert-rows commit path). The insert statements themselves succeeded or failed earlier; this error means the final connection.commit() call failed, so the inserted rows may not be durably committed. It distinguishes batch-update failures (which produce a KettleDatabaseBatchException instead).
Solutions
- Inspect the wrapped cause (getCause()) for the real SQLException message and fix the underlying SQL/constraint problem
- Verify the connection is still open and healthy before committing; increase connection/transaction timeouts for long batches
- Check for constraint violations (FK, unique, check) that only surface at COMMIT and pre-validate or correct the incoming rows
- Catch KettleDatabaseException around insertRow/commit calls and implement rollback + retry with a fresh connection
Example fix
// before
database.insertRow(tableMeta, rowMeta, row);
// after
try {
database.insertRow(tableMeta, rowMeta, row);
} catch (KettleDatabaseException e) {
logError("Commit after insert failed: " + e.getCause());
database.rollback();
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!database.isOpened()) throw new IllegalStateException("Connection must be open before inserting/committing"); Try / catch
try {
database.insertRow(tableMeta, rowMeta, row);
} catch (KettleDatabaseException e) {
Throwable cause = e.getCause();
logError("Insert/commit failed: " + (cause != null ? cause.getMessage() : e.getMessage()));
database.rollback();
// reconnect and retry or rethrow
} Prevention
- Keep transactions short; commit in smaller batches to reduce exposure to connection drops
- Increase network/transaction timeouts for long-running transformations
- Pre-validate constraint-sensitive data before inserting
- Monitor and reconnect on connection-staleness between batches
When it happens
Trigger: Calling Database.insertRow(...) with commit enabled / commitInsert() when connection.commit() throws SQLException — e.g. the connection was closed or broken mid-batch, a constraint/deferred-trigger violation surfaces only at commit, or the transaction was already rolled back by the driver.
Common situations: Long-running transformations where the DB connection times out or is killed by the network between inserts; deferred foreign-key or check constraints failing at COMMIT time; the transaction being aborted server-side (e.g. PostgreSQL 'current transaction is aborted'); calling commit after closing the connection in custom steps.
Related errors
- Error comitting connection
- Database.Exception.UnableToDisableAutoCommit
- Database.Exception.UnableToEnableAutoCommit
- Database.Exception.UnableToReleaseSavepoint
- Database.Exception.UnableToRollbackToSavepoint
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/a8a21fc2d3e70e51.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/database/Database.java:1793
isBatchUpdate = true;
ps.executeBatch();
commit();
} else {
commit();
}
}
// Let's not forget to close the prepared statement.
//
ps.close();
}
} catch ( BatchUpdateException ex ) {
throw createKettleDatabaseBatchException( "Error updating batch", ex );
} catch ( SQLException ex ) {
if ( isBatchUpdate ) {
throw createKettleDatabaseBatchException( "Error updating batch", ex );
} else {
throw new KettleDatabaseException( "Unable to commit connection after having inserted rows.", ex );
}
}
}
/**
* Execute an SQL statement on the database connection (has to be open)
*
* @param sql The SQL to execute
* @return a Result object indicating the number of lines read, deleted, inserted, updated, ...
* @throws KettleDatabaseException in case anything goes wrong.
*/
public Result execStatement( String sql ) throws KettleDatabaseException {
return execStatement( sql, null, null );
}
public Result execStatement( String rawsql, RowMetaInterface params, Object[] data ) throws KettleDatabaseException {
Result result = new Result();
View on GitHub (pinned to f3058517a1)