{"record":{"id":"f7964c949be4bce6","repo":"pentaho/pentaho-kettle","slug":"error-performing-rollback-on-connection","errorCode":null,"errorMessage":"Error performing rollback on connection","messagePattern":"Error performing rollback on connection","errorType":"exception","errorClass":"KettleDatabaseException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/database/Database.java","lineNumber":1202,"sourceCode":"  public void rollback( boolean force ) throws KettleDatabaseException {\n    try {\n      if ( !Utils.isEmpty( connectionGroup ) && !force ) {\n        return; // Will be handled by Trans --> endProcessing()\n      }\n      if ( getDatabaseMetaData().supportsTransactions() ) {\n        if ( connection != null ) {\n          if ( log.isDebug() ) {\n            log.logDebug( \"Rollback on database connection [\" + toString() + \"]\" );\n          }\n          connection.rollback();\n        }\n      } else {\n        if ( log.isDetailed() ) {\n          log.logDetailed( \"No rollback possible on database connection [\" + toString() + \"]\" );\n        }\n      }\n    } catch ( SQLException e ) {\n      throw new KettleDatabaseException( \"Error performing rollback on connection\", e );\n    }\n  }\n\n  /**\n   * Prepare inserting values into a table, using the fields & values in a Row\n   *\n   * @param rowMeta   The row metadata to determine which values need to be inserted\n   * @param tableName The name of the table in which we want to insert rows\n   * @throws KettleDatabaseException if something went wrong.\n   */\n  public void prepareInsert( RowMetaInterface rowMeta, String tableName ) throws KettleDatabaseException {\n    prepareInsert( rowMeta, null, tableName );\n  }\n\n  /**\n   * Prepare inserting values into a table, using the fields & values in a Row\n   *\n   * @param rowMeta    The metadata row to determine which values need to be inserted","sourceCodeStart":1184,"sourceCodeEnd":1220,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/database/Database.java#L1184-L1220","documentation":"KettleDatabaseException thrown by Database.rollback() when connection.rollback() throws a SQLException. The transaction could not be rolled back — often because the connection itself is already dead, in which case the server rolls back implicitly. Callers should treat the connection as unusable afterwards.","triggerScenarios":"Calling Database.rollback() when connection.rollback() throws SQLException — connection terminated by DB/network, rollback attempted in a distributed (XA) context incorrectly, or statement/transaction already completed by the driver.","commonSituations":"Error-handling paths that roll back after a network failure (rollback then fails too), DB killed the session (wait_timeout), rollback on an autocommit connection.","solutions":["Assume the connection is dead: close it and reconnect; the server will have rolled back the open transaction implicitly","Check the wrapped SQLException for 'connection closed'-type messages to confirm the connection was already lost","Avoid rollback loops — guard cleanup code so a failed rollback does not mask the original error","Verify the connection is not in autocommit mode where rollback is a no-op or unsupported"],"exampleFix":"// before\ntry { database.commit(); } finally { database.rollback(); }\n// after\ntry {\n  database.commit();\n} catch ( Exception e ) {\n  try {\n    database.rollback();\n  } catch ( KettleDatabaseException re ) {\n    log.warn(\"Rollback failed, connection likely dead; reconnecting\");\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"Connection c = database.getConnection();\nif ( c == null || c.isClosed() ) {\n  return; // server already rolled back implicitly\n}","typeGuard":"boolean canRollback( Database db ) throws SQLException {\n  Connection c = db.getConnection();\n  return c != null && !c.isClosed();\n}","tryCatchPattern":"try {\n  database.rollback();\n} catch ( KettleDatabaseException e ) {\n  log.warn( \"Rollback failed; reconnecting so server-side rollback applies\" );\n  database.disconnect();\n}","preventionTips":["Do not let rollback failures mask the original exception","Reconnect after a failed rollback — dead connections imply implicit server rollback","Keep transactions short and validate connection health before rollback"],"tags":["jdbc","database","rollback","transaction"],"backgroundTag":"database-query-failed","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}