lohitkolluri commented on code in PR #67900:
URL: https://github.com/apache/airflow/pull/67900#discussion_r3353183297


##########
airflow-core/src/airflow/models/backfill.py:
##########
@@ -653,7 +653,7 @@ def _create_backfill(
             triggering_user_name=triggering_user_name,
         )
         session.add(br)
-        session.commit()
+        session.flush()

Review Comment:
   Thanks for the suggestion — it's a cleaner approach than the early 
`session.commit()`. I've implemented it:
   
   - Added `with_row_locks()` on the DagModel query before the `num_active` 
check. On PG/MySQL, `FOR UPDATE` serializes concurrent backfill creation for 
the same dag — requests queue up behind the lock, so they can't both see 
`num_active=0`. On SQLite it's a no-op (single-writer), so no change in 
behavior there.
   
   - Replaced `session.commit()` with `session.flush()` — the flush populates 
the auto-generated backfill ID for the `backfill_dag_run` FK, while keeping 
everything in one atomic transaction. The outer `create_session()` context 
commits everything together, so if DagRun creation fails, the backfill is 
rolled back too — no more orphaned backfill.
   
   Re deadlock concern: I traced the call paths inside `_create_backfill`. The 
DagModel `FOR UPDATE` is on a single row (`WHERE dag_id = ?`), acquired before 
any DagRun-level locks. The only other lock-taking path (`with_row_locks` in 
`_create_backfill_dag_run_non_partitioned`) locks DagRun rows, not DagModel 
rows, so lock ordering is consistent. No deadlock risk.
   
   Pushed in the latest commit — mind taking another look?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to