fix(dataset_service): use flush() instead of commit() to preserve caller transaction (#39223)

This commit is contained in:
Checo 2026-07-19 15:00:50 +08:00 committed by GitHub
parent 2ec34b2cfb
commit 5ea884f799
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 21 additions and 6 deletions

View File

@ -739,8 +739,13 @@ class DatasetService:
dataset.id, external_knowledge_id, external_knowledge_api_id, session
)
# Commit changes to database
session.commit()
# Flush changes to the database without closing the caller-managed
# transaction. This helper receives a session opened by the caller
# (`with Session(...) as session`); calling commit() here closed that
# context manager early and raised
# sqlalchemy.exc.InvalidRequestError: Can't operate on closed transaction
# (#39191).
session.flush()
return dataset
@ -810,9 +815,15 @@ class DatasetService:
if data.get("icon_info"):
filtered_data["icon_info"] = data.get("icon_info")
# Update dataset in database
# Update dataset in database. Use flush() rather than commit() so the
# caller-managed transaction (opened with `with Session(...) as session`)
# stays open for subsequent operations — _update_pipeline_knowledge_base
# node data and any caller follow-ups run on the same session. Calling
# commit() here closed the context manager early and raised
# sqlalchemy.exc.InvalidRequestError: Can't operate on closed transaction
# (#39191).
session.execute(update(Dataset).where(Dataset.id == dataset.id).values(**filtered_data))
session.commit()
session.flush()
# Reload dataset to get updated values
session.refresh(dataset)

View File

@ -631,7 +631,9 @@ class TestDatasetServiceCreationAndUpdate:
get_external_knowledge_api.assert_called_once_with("api-1", dataset.tenant_id, session=session)
update_binding.assert_called_once_with("dataset-1", "knowledge-1", "api-1", session)
session.add.assert_called_once_with(dataset)
session.commit.assert_called_once()
# flush() (not commit()) preserves the caller-managed transaction (#39191)
session.flush.assert_called_once()
session.commit.assert_not_called()
@pytest.mark.parametrize(
("payload", "message"),
@ -728,7 +730,9 @@ class TestDatasetServiceCreationAndUpdate:
assert "external_knowledge_api_id" not in updated_values
assert "external_knowledge_id" not in updated_values
assert "external_retrieval_model" not in updated_values
session.commit.assert_called_once()
# flush() (not commit()) preserves the caller-managed transaction (#39191)
session.flush.assert_called_once()
session.commit.assert_not_called()
session.refresh.assert_called_once_with(dataset)
update_pipeline.assert_called_once_with(dataset, "user-1", session)
vector_task.delay.assert_called_once_with("dataset-1", "update")