refactor(task): enhance UpdateWithStatus for CAS updates and add integration tests

- Updated UpdateWithStatus method to use Model().Select("*").Updates() for conditional updates, preventing GORM's INSERT fallback.
- Introduced comprehensive integration tests for UpdateWithStatus, covering scenarios for winning and losing CAS updates, as well as concurrent updates.
- Added task_cas_test.go to validate the new behavior and ensure data integrity during concurrent state transitions.
This commit is contained in:
CaIon
2026-02-22 01:25:04 +08:00
parent b386490d5e
commit 374aabf301
4 changed files with 831 additions and 2 deletions

View File

@@ -388,8 +388,12 @@ func (Task *Task) Update() error {
// UpdateWithStatus performs a conditional UPDATE guarded by fromStatus (CAS).
// Returns (true, nil) if this caller won the update, (false, nil) if
// another process already moved the task out of fromStatus.
//
// Uses Model().Select("*").Updates() instead of Save() because GORM's Save
// falls back to INSERT ON CONFLICT when the WHERE-guarded UPDATE matches
// zero rows, which silently bypasses the CAS guard.
func (t *Task) UpdateWithStatus(fromStatus TaskStatus) (bool, error) {
result := DB.Where("status = ?", fromStatus).Save(t)
result := DB.Model(t).Where("status = ?", fromStatus).Select("*").Updates(t)
if result.Error != nil {
return false, result.Error
}