{"record":{"id":"ab3fefeb991fb6d6","repo":"apache/seatunnel","slug":"flush-data-failed-ab3fef","errorCode":"FLUSH_DATA_FAILED","errorMessage":"Writing records to JDBC failed.","messagePattern":"Writing records to JDBC failed\\.","errorType":"error_code","errorClass":"JdbcConnectorException","httpStatus":null,"severity":"critical","filePath":"seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/JdbcOutputFormat.java","lineNumber":100,"sourceCode":"        lastFlushTimeMs = System.currentTimeMillis();\n    }\n\n    private E createAndOpenStatementExecutor(StatementExecutorFactory<E> statementExecutorFactory) {\n        E exec = statementExecutorFactory.get();\n        try {\n            exec.prepareStatements(connectionProvider.getConnection());\n        } catch (SQLException e) {\n            throw new JdbcConnectorException(\n                    CommonErrorCodeDeprecated.SQL_OPERATION_FAILED,\n                    \"unable to open JDBC writer\",\n                    e);\n        }\n        return exec;\n    }\n\n    public void checkFlushException() {\n        if (flushException != null) {\n            throw new JdbcConnectorException(\n                    CommonErrorCodeDeprecated.FLUSH_DATA_FAILED,\n                    \"Writing records to JDBC failed.\",\n                    flushException);\n        }\n    }\n\n    public final synchronized void writeRecord(I record) {\n        writeRecordWithAutoFlush(record);\n    }\n\n    public final synchronized boolean writeRecordWithAutoFlush(I record) {\n        checkFlushException();\n        try {\n            addToBatch(record);\n            batchCount++;\n            if (batchCount > 0 && (isOverMaxBatchSizeLimit() || isOverMaxBatchIntervalLimit())) {\n                flush();\n                return true;","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/JdbcOutputFormat.java#L82-L118","documentation":"JdbcOutputFormat caches the first flush/write exception (flushException); checkFlushException rethrows it as JdbcConnectorException FLUSH_DATA_FAILED 'Writing records to JDBC failed.' wrapping the original cause. Once set, every subsequent checkFlushException (from writeRecordWithAutoFlush/close) fails fast instead of continuing with a broken writer.","triggerScenarios":"A prior flush or batch write threw (connection lost, deadlock, constraint violation, timeout), setting flushException; the next checkFlushException call — from writeRecordWithAutoFlush or close — surfaces it.","commonSituations":"Network drop mid-batch, lock wait timeout on hot rows, duplicate-key or NOT NULL constraint violations, transaction aborted server-side, DB failover while batch pending.","solutions":["Inspect the wrapped flushException cause for the driver-level error","Fix the root cause: network stability, constraint conflicts, lock contention, or DB failover handling","Enable/raise flush retries and interval (connection recovery options on the sink)","Validate incoming data against table constraints to prevent repeated batch failures","Restart the failed task after the database is healthy — the writer is unrecoverable after this error"],"exampleFix":"// before\n// duplicate primary keys poison the batch\nINSERT INTO t(id) VALUES (1); -- second time: duplicate key -> flushException\n// after\nsink options: { generate_upsert_sql = true } // use UPSERT for idempotent writes","handlingStrategy":"retry","validationCode":"// validate data against constraints before writing\nSELECT count(*) FROM staging s LEFT JOIN target t ON s.pk = t.pk\nWHERE t.pk IS NOT NULL; // duplicates would poison batches","typeGuard":null,"tryCatchPattern":"try {\n    outputFormat.writeRecord(record);\n} catch (JdbcConnectorException e) {\n    if (e.getErrorCode() == CommonErrorCodeDeprecated.FLUSH_DATA_FAILED) {\n        LOG.error(\"flush failed permanently: {}\", e.getCause(), e);\n        restartFromCheckpoint(); // writer is unusable after flushException\n    } else {\n        throw e;\n    }\n}","preventionTips":["Use upsert SQL for idempotent writes to avoid duplicate-key failures","Enable the sink's connection retry/recovery options","Check lock contention and lock_wait_timeout on hot tables","Monitor DB failover events; restart tasks after failover","Validate data against NOT NULL/constraints before writing"],"tags":["jdbc","flush","sink","write"],"backgroundTag":"database-write-failed","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}