Skip to content

Fix dynamically mapped tasks never running on scheduled Dag runs - #74861

Merged
vatsrahul1001 merged 1 commit into
apache:mainfrom
astronomer:fix-dynamic-region-commit-guard
Oct 17, 2026
Merged

vatsrahul1001 merged 1 commit into
apache:mainfrom
astronomer:fix-dynamic-region-commit-guard

Conversation

@vatsrahul1001

Copy link
Copy Markdown
Contributor

DynamicRegion.get_or_create_many() uses a SAVEPOINT (session.begin_nested()) to safely insert dynamic-mapping regions. Releasing that SAVEPOINT dispatches the same before_commit event as a real commit, and the scheduler's CommitProhibitorGuard rejected it unconditionally, raising "UNEXPECTED COMMIT - THIS WILL BREAK HA LOCKS!" before the Dag run's task instances could be created.

This only happened for a Dag run the scheduler created from its own schedule: the API server's Dag run creation runs outside the scheduler's guarded session, so the identical SAVEPOINT release there was harmless. A dynamically mapped task on a real (non-manually-triggered) schedule could therefore never run, with the same scheduling error repeating every loop.

Releasing a savepoint ends neither the outer transaction nor its row locks, so it cannot break the HA locks this guard protects — only the outer commit can, and that remains guarded.

Tested against a minimal repro Dag (scheduled .expand() task) that reproduced the failure before this change and runs clean after it. Also added a unit test covering the guard directly: a savepoint release inside prohibit_commit no longer raises, while a real commit still does.

closes: #74860


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 5)

Generated-by: Claude Code (Opus 5) following the guidelines

@vatsrahul1001
vatsrahul1001 force-pushed the fix-dynamic-region-commit-guard branch from af08040 to 65109b0 Compare October 16, 2026 15:20
Comment thread airflow-core/tests/unit/utils/test_sqlalchemy.py
Comment thread airflow-core/src/airflow/utils/sqlalchemy.py
Comment thread airflow-core/tests/unit/utils/test_sqlalchemy.py
DynamicRegion.get_or_create_many() uses a SAVEPOINT (session.begin_nested())
to safely insert dynamic-mapping regions. Releasing that SAVEPOINT dispatches
the same before_commit event as a real commit, and the scheduler's
CommitProhibitorGuard rejected it unconditionally, raising "UNEXPECTED
COMMIT - THIS WILL BREAK HA LOCKS!" before the Dag run's task instances
could be created.

This only happened for a Dag run the scheduler created from its own
schedule: the API server's Dag run creation runs outside the scheduler's
guarded session, so the identical SAVEPOINT release there was harmless. A
dynamically mapped task on a real (non-manually-triggered) schedule could
therefore never run, with the same scheduling error repeating every loop.

Releasing a savepoint ends neither the outer transaction nor its row locks,
so it cannot break the HA locks this guard protects -- only the outer
commit can, and that remains guarded.
@vatsrahul1001
vatsrahul1001 force-pushed the fix-dynamic-region-commit-guard branch from 65109b0 to 45e947b Compare October 16, 2026 16:20
@vatsrahul1001 vatsrahul1001 added this to the Airflow 3.4.0 milestone Oct 16, 2026
@vatsrahul1001 vatsrahul1001 added the backport-to-v3-4-test Backport to v3-4-test label Oct 16, 2026
@vatsrahul1001
vatsrahul1001 merged commit f5038e6 into apache:main Oct 17, 2026
78 of 79 checks passed
@vatsrahul1001
vatsrahul1001 deleted the fix-dynamic-region-commit-guard branch October 17, 2026 13:17
@github-actions

Copy link
Copy Markdown
Contributor

Backport successfully created: v3-4-test

Note: As of Merging PRs targeted for Airflow 3.X
the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.

In matter of doubt please ask in #release-management Slack channel.

Status Branch Result
✅ v3-4-test PR Link

vatsrahul1001 added a commit that referenced this pull request Oct 18, 2026
…ag runs (#74861) (#74918)

DynamicRegion.get_or_create_many() uses a SAVEPOINT (session.begin_nested())
to safely insert dynamic-mapping regions. Releasing that SAVEPOINT dispatches
the same before_commit event as a real commit, and the scheduler's
CommitProhibitorGuard rejected it unconditionally, raising "UNEXPECTED
COMMIT - THIS WILL BREAK HA LOCKS!" before the Dag run's task instances
could be created.

This only happened for a Dag run the scheduler created from its own
schedule: the API server's Dag run creation runs outside the scheduler's
guarded session, so the identical SAVEPOINT release there was harmless. A
dynamically mapped task on a real (non-manually-triggered) schedule could
therefore never run, with the same scheduling error repeating every loop.

Releasing a savepoint ends neither the outer transaction nor its row locks,
so it cannot break the HA locks this guard protects -- only the outer
commit can, and that remains guarded.
(cherry picked from commit f5038e6)

Co-authored-by: Rahul Vats <43964496+vatsrahul1001@users.noreply.github.com>
vatsrahul1001 added a commit that referenced this pull request Oct 20, 2026
…ag runs (#74861) (#74918)

DynamicRegion.get_or_create_many() uses a SAVEPOINT (session.begin_nested())
to safely insert dynamic-mapping regions. Releasing that SAVEPOINT dispatches
the same before_commit event as a real commit, and the scheduler's
CommitProhibitorGuard rejected it unconditionally, raising "UNEXPECTED
COMMIT - THIS WILL BREAK HA LOCKS!" before the Dag run's task instances
could be created.

This only happened for a Dag run the scheduler created from its own
schedule: the API server's Dag run creation runs outside the scheduler's
guarded session, so the identical SAVEPOINT release there was harmless. A
dynamically mapped task on a real (non-manually-triggered) schedule could
therefore never run, with the same scheduling error repeating every loop.

Releasing a savepoint ends neither the outer transaction nor its row locks,
so it cannot break the HA locks this guard protects -- only the outer
commit can, and that remains guarded.
(cherry picked from commit f5038e6)

Co-authored-by: Rahul Vats <43964496+vatsrahul1001@users.noreply.github.com>
SameerMesiah97 pushed a commit to SameerMesiah97/airflow-oss-sm97 that referenced this pull request Oct 27, 2026
…che#74861)

DynamicRegion.get_or_create_many() uses a SAVEPOINT (session.begin_nested())
to safely insert dynamic-mapping regions. Releasing that SAVEPOINT dispatches
the same before_commit event as a real commit, and the scheduler's
CommitProhibitorGuard rejected it unconditionally, raising "UNEXPECTED
COMMIT - THIS WILL BREAK HA LOCKS!" before the Dag run's task instances
could be created.

This only happened for a Dag run the scheduler created from its own
schedule: the API server's Dag run creation runs outside the scheduler's
guarded session, so the identical SAVEPOINT release there was harmless. A
dynamically mapped task on a real (non-manually-triggered) schedule could
therefore never run, with the same scheduling error repeating every loop.

Releasing a savepoint ends neither the outer transaction nor its row locks,
so it cannot break the HA locks this guard protects -- only the outer
commit can, and that remains guarded.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-to-v3-4-test Backport to v3-4-test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DynamicRegion.get_or_create_many() breaks scheduler-created DagRuns for dynamically mapped tasks (UNEXPECTED COMMIT - THIS WILL BREAK HA LOCKS!)

4 participants