apache/seatunnel · critical · JdbcConnectorException

XA_OPERATION_FAILED

XA_OPERATION_FAILED

Error message

reached max number of commit attempts (%d) for transactions: %s

What it means

XaGroupOpsImpl tracks how many times each pending XA transaction's commit has been retried. throwIfAnyReachedMaxAttempts is called from commit and, when one or more transactions have been attempted maxAttempts times without success, throws XA_OPERATION_FAILED listing the transactions. This prevents infinite commit retry loops on transactions that can never commit.

Solutions

  1. Inspect the listed transactions on the database side (XA recovery / in-doubt transactions) and manually commit or rollback them.
  2. Increase the configured max commit attempts to tolerate transient outages.
  3. Fix the root connectivity/authorization failure causing commits to keep failing.
  4. After manual recovery, restart the job; pending transactions should be recoverable via XA recovery.

Example fix

// before
max_commit_attempts = 3
// after
max_commit_attempts = 10
Defensive patterns

Strategy: retry

Validate before calling

// monitor pending XA transactions before they exhaust attempts
// SELECT * FROM pg_prepared_xacts;  -- PostgreSQL in-doubt transactions

Try / catch

try {
  xaGroupOps.commit(xids);
} catch (JdbcConnectorException e) {
  if (e.getMessage() != null && e.getMessage().contains("reached max number of commit attempts")) {
    // resolve in-doubt XAs manually on the DB, then restart job for XA recovery
  }
  throw e;
}

Prevention

When it happens

Trigger: Repeated checkpoint/commit cycles where the database persistently rejects XA commit (e.g. the transaction is in a heuristic or abandoned state, or connection failures recur) until maxCommitAttempts is reached.

Common situations: Database outage during multiple checkpoints; a stuck 'in-doubt' transaction that needs manual XA recovery; too-low configured max attempts combined with flaky network.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/b48e25be7aa941f4. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/xa/XaGroupOpsImpl.java:162

                    LOG.info("unable to rollback recovered transaction, xid={}", xid, e);
                }
            }
        }
    }

    private static void throwIfAnyReachedMaxAttempts(
            GroupXaOperationResult<XidInfo> result, int maxAttempts) {
        List<XidInfo> reached = null;
        for (XidInfo x : result.getForRetry()) {
            if (x.getAttempts() >= maxAttempts) {
                if (reached == null) {
                    reached = new ArrayList<>();
                }
                reached.add(x);
            }
        }
        if (reached != null) {
            throw new JdbcConnectorException(
                    JdbcConnectorErrorCode.XA_OPERATION_FAILED,
                    String.format(
                            "reached max number of commit attempts (%d) for transactions: %s",
                            maxAttempts, reached));
        }
    }
}

View on GitHub (pinned to cf67b549a7)