fix: duplicate document ingest guard (#15638)

### What problem does this PR solve?
When a document is rerun or updated concurrently, the previous
unconditional update could overwrite a newer task state.
This change adds an `update_time`-based optimistic lock so the update
only succeeds if the record has not been modified by another flow in the
meantime.

### Type of change
- [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
buua436
2026-06-04 17:57:51 +08:00
committed by GitHub
parent baeb0c0431
commit 423fb6faae
2 changed files with 36 additions and 3 deletions

View File

@@ -276,6 +276,26 @@ class CommonService:
num = cls.model.update(data).where(cls.model.id == pid).execute()
return num
@classmethod
@DB.connection_context()
@retry_db_operation
def update_by_id_if_update_time(cls, pid, update_time, data):
# Update a single record by ID only if update_time matches the expected value.
# Args:
# pid: Record ID
# update_time: Expected update_time value for optimistic locking
# data: Updated field values
# Returns:
# Number of records updated
data["update_time"] = current_timestamp()
data["update_date"] = datetime_format(datetime.now())
num = (
cls.model.update(data)
.where(cls.model.id == pid, cls.model.update_time == update_time)
.execute()
)
return num
@classmethod
@DB.connection_context()
def get_by_id(cls, pid):