debusine:task-history collection cleanup strategy can result in deadlocks

I ran into a confusing deadlock on production that caused a UpdateWorkRequestAsCompletedView failure, logged as follows:

        Process 478184: UPDATE "db_collectionitem" SET "name" = 'Worker:autopkgtest:twine:amd64%3Aincus-lxc:336390', "child_type" = 'b', "category" = 'debusine:historical-task-run', "parent_collection_id" = 141, "parent_category" = 'debusine:task-history', "collection_id" = NULL, "artifact_id" = NULL, "data" = '{"result": "success", "context": "amd64:incus-lxc", "subject": "twine", "task_name": "autopkgtest", "task_type": "Worker", "timestamp": 1768257910, "work_request_id": 336390, "runtime_statistics": {"cpu_time": 42, "duration": 43, "cpu_count": null, "available_memory": null, "available_disk_space": null}}'::jsonb, "created_at" = '2026-01-12 22:46:00.970013+00:00'::timestamptz, "created_by_user_id" = 26, "created_by_workflow_id" = 336389, "removed_at" = '2026-03-10 22:28:21.425877+00:00'::timestamptz, "removed_by_user_id" = 5, "removed_by_workflow_id" = 506088 WHERE "db_collectionitem"."id" = 2861908
        Process 478060: UPDATE "db_collectionitem" SET "name" = 'Worker:autopkgtest:rubygems:amd64%3Aincus-lxc:91468', "child_type" = 'b', "category" = 'debusine:historical-task-run', "parent_collection_id" = 141, "parent_category" = 'debusine:task-history', "collection_id" = NULL, "artifact_id" = NULL, "data" = '{"result": "failure", "context": "amd64:incus-lxc", "subject": "rubygems", "task_name": "autopkgtest", "task_type": "Worker", "timestamp": 1746635208, "work_request_id": 91468, "runtime_statistics": {"cpu_time": 232, "duration": 229, "cpu_count": null, "available_memory": null, "available_disk_space": null}}'::jsonb, "created_at" = '2025-05-07 16:30:38.205231+00:00'::timestamptz, "created_by_user_id" = 55, "created_by_workflow_id" = 91467, "removed_at" = '2026-03-10 22:28:21.441582+00:00'::timestamptz, "removed_by_user_id" = 96, "removed_by_workflow_id" = 507386 WHERE "db_collectionitem"."id" = 1367342

This was confusing until I noticed that these are both for rather old items that are being removed, and so the deadlock is most likely in the code in TaskHistory.do_add_bare_data that cleans up old items. Since this runs from event reactions, it's risky to do this sort of operation here. We should move this to the expiry job instead.