{"record":{"id":"3f1071c6056d436b","repo":"apache/iceberg","slug":"view-was-updated-concurrently-s","errorCode":null,"errorMessage":"View was updated concurrently: %s","messagePattern":"View was updated concurrently: (.+?)","errorType":"exception","errorClass":"AlreadyExistsException","httpStatus":409,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/view/BaseMetastoreViewCatalog.java","lineNumber":271,"sourceCode":"              .build();\n\n      properties.putAll(viewOverrideProperties());\n\n      ViewMetadata.Builder builder =\n          ViewMetadata.buildFrom(metadata)\n              .setProperties(properties)\n              .setCurrentVersion(viewVersion, schema);\n\n      if (null != location) {\n        builder.setLocation(location);\n      }\n\n      ViewMetadata replacement = builder.build();\n\n      try {\n        ops.commit(metadata, replacement);\n      } catch (CommitFailedException ignored) {\n        throw new AlreadyExistsException(\"View was updated concurrently: %s\", identifier);\n      }\n\n      return new BaseView(ops, ViewUtil.fullViewName(name(), identifier));\n    }\n  }\n\n  @Override\n  public TableBuilder buildTable(TableIdentifier identifier, Schema schema) {\n    return new BaseMetastoreViewCatalogTableBuilder(identifier, schema);\n  }\n\n  /** The purpose of this class is to add view detection when replacing a table */\n  protected class BaseMetastoreViewCatalogTableBuilder extends BaseMetastoreCatalogTableBuilder {\n    private final TableIdentifier identifier;\n\n    public BaseMetastoreViewCatalogTableBuilder(TableIdentifier identifier, Schema schema) {\n      super(identifier, schema);\n      this.identifier = identifier;","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/view/BaseMetastoreViewCatalog.java#L253-L289","documentation":"This AlreadyExistsException is thrown when a createOrReplace or replace operation's commit fails because the view's metadata changed concurrently (CommitFailedException). The catalog cannot guarantee a clean replacement, so it reports that another writer updated the view between this operation's read and commit.","triggerScenarios":"Calling catalog.replaceView(...) or createOrReplace on a view while another client/process modifies or deletes the same view; the optimistic-concurrency commit in ops.commit raises CommitFailedException and this message is thrown instead.","commonSituations":"Multiple jobs or engine sessions (Spark, Trino, Flink) writing the same view definition concurrently; retry storms after a failed commit; long-running replacement transactions racing with quick updates.","solutions":["Re-read the view (catalog.loadView) to get fresh metadata, then retry the replace","Coordinate writers so only one process replaces a given view at a time","Use a replaceTransaction with proper row-level conflict handling if this races frequently","Check the underlying metastore for unusual concurrent writer activity or misconfigured retries"],"exampleFix":"// before\ncatalog.replaceView(identifier).withQuery(\"sql\", query).createOrReplace();\n// after\nif (catalog.viewExists(identifier)) {\n  try {\n    catalog.replaceView(identifier).withQuery(\"sql\", query).createOrReplace();\n  } catch (AlreadyExistsException e) {\n    // view changed concurrently; refresh and retry\n    catalog.replaceView(identifier).withQuery(\"sql\", query).createOrReplace();\n  }\n}","handlingStrategy":"try-catch","validationCode":"boolean canReplace = catalog.viewExists(identifier); // and ensure single-writer coordination externally","typeGuard":null,"tryCatchPattern":"try { catalog.replaceView(ident).withQuery(\"sql\", q).createOrReplace(); } catch (AlreadyExistsException e) { // reload view and retry }","preventionTips":["Serialize view replacements through a single writer or coordination mechanism","Retry replace operations after refreshing metadata","Keep view update transactions short to shrink the race window"],"tags":["concurrency","view","commit-conflict","optimistic-locking"],"backgroundTag":"invalid-state-transition","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}