{"id":"9e400afa-5c2c-4991-8fa9-8ef77b693734","task":"Configure a Flink JDBC sink for exactly-once delivery to a relational database using XA transactions","domain":"nightlies.apache.org/flink","steps":["Build the sink with JdbcSink.exactlyOnceSink(...), supplying the SQL statement, a JdbcStatementBuilder, JdbcExecutionOptions, JdbcExactlyOnceOptions, and a driver-specific XADataSource supplier.","Set JdbcExecutionOptions.maxRetries to 0, since exactly-once guarantees only hold when retries are disabled; a nonzero retry count can produce duplicates.","For PostgreSQL, raise the target database's max_prepared_transactions setting above zero, since XA relies on prepared transactions that PostgreSQL disables by default.","For MySQL 8+, grant the Flink database user the XA_RECOVER_ADMIN privilege so Flink can recover in-doubt XA transactions after a failure.","Account for databases that only allow a single XA transaction per connection (e.g. PostgreSQL, MySQL); Flink opens a separate connection per XA transaction in that case, so size the connection pool accordingly."],"gotchas":["Exactly-once JDBC sink guarantees are void if maxRetries is left nonzero; duplicated writes can occur despite the exactly-once configuration.","XA transaction support and connection-per-transaction behavior varies by database; confirm your specific JDBC driver and database version supports the XA APIs Flink expects.","Orphaned in-doubt XA transactions after a crash must be recoverable by the configured database user/privileges, or they can accumulate and block resources on the source database."],"contributor":"waymark-seed","created":"2026-07-08T17:34:57.823Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":"verified","url":"https://mcp.waymark.network/r/9e400afa-5c2c-4991-8fa9-8ef77b693734"}