Take a look at this code-snippet. I tried to isolate it. Assume you have > 100 records in the database that match the query
repeat
FAllInProgressTasks := FManager.Find<TDatabaseTask>.
Add(TExpression.Eq('TaskState', tsInProgress)).Take(100).List;
try
if FAllInProgressTasks.Count > 0 then
begin
FLog.Display('Run');
FManager.BatchSize := FAllInProgressTasks.Count;
FManager.CachedUpdates := true;
try
for nX := FAllInProgressTasks.Count - 1 downto 0 do
begin
FTask := FAllInProgressTasks.Items[nX];
FTask.TaskState := tsRestart;
FManager.Update(FTask);
end;
finally
FManager.ApplyUpdates;
FManager.CachedUpdates := false; // If you don't turn off CachedUpdates here the second run will fail and generate an exception
end;
end
else
FReady := true;
FManager.Flush;
finally
FAllInProgressTasks.Free;
end;
FManager.Clear;
until FReady;
If you dont set the CachedUpdates to false after ApplyUpdates, the second time it will fail and generate an exception.
The operation which caches the modification is Flush, not Update. You are calling Flush and then calling Clear, destroying the objects but keeping the cached updates in memory. Change your code to this:
repeat
FAllInProgressTasks := FManager.Find<TDatabaseTask>.
Add(TExpression.Eq('TaskState', tsInProgress)).Take(100).List;
try
if FAllInProgressTasks.Count > 0 then
begin
FLog.Display('Run');
FManager.BatchSize := FAllInProgressTasks.Count;
FManager.CachedUpdates := true;
try
for nX := FAllInProgressTasks.Count - 1 downto 0 do
begin
FTask := FAllInProgressTasks.Items[nX];
FTask.TaskState := tsRestart;
FManager.Flush(FTask);
end;
finally
FManager.ApplyUpdates;
FManager.CachedUpdates := false; // If you don't turn off CachedUpdates here the second run will fail and generate an exception
end;
end
else
FReady := true;
finally
FAllInProgressTasks.Free;
end;
FManager.Clear;
until FReady;