Skip to content

Commit 315d159

Browse files
authored
Fix deadlock in ti_update_state caused by FOR UPDATE locking dag_run (#67246)
session.get(TI, id, with_for_update=True) emits a SELECT that joins dag_run (via the lazy="joined" relationship) and applies FOR UPDATE to both tables. Under concurrent task completions this serialises all workers on the same dag_run row, producing deadlock cycles with the scheduler's trigger-rule dependency checks. Three other callsites in this file already use with_for_update={"of": TI} for exactly this reason. Apply the same fix to the two remaining callsites in _create_ti_state_update_query_and_update_state and its error-recovery path.
1 parent cb2aaf4 commit 315d159

1 file changed

Lines changed: 2 additions & 2 deletions

File tree

airflow-core/src/airflow/api_fastapi/execution_api/routes/task_instances.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ def ti_update_state(
430430
"Error updating Task Instance state. Setting the task to failed.",
431431
payload=ti_patch_payload,
432432
)
433-
ti = session.get(TI, task_instance_id, with_for_update=True)
433+
ti = session.get(TI, task_instance_id, with_for_update={"of": TI})
434434
if session.bind is not None:
435435
query = TI.duration_expression_update(timezone.utcnow(), query, session.bind)
436436
query = query.values(state=(updated_state := TaskInstanceState.FAILED))
@@ -558,7 +558,7 @@ def _create_ti_state_update_query_and_update_state(
558558
dag_id: str,
559559
) -> tuple[Update, TaskInstanceState]:
560560
if isinstance(ti_patch_payload, (TITerminalStatePayload, TIRetryStatePayload, TISuccessStatePayload)):
561-
ti = session.get(TI, task_instance_id, with_for_update=True)
561+
ti = session.get(TI, task_instance_id, with_for_update={"of": TI})
562562
updated_state = TaskInstanceState(ti_patch_payload.state.value)
563563
if session.bind is not None:
564564
query = TI.duration_expression_update(ti_patch_payload.end_date, query, session.bind)

0 commit comments

Comments
 (0)