I strongly agree with Mentallurg's assessment – if you can do it.
If for whatever reason you need to stick with files, then I can actually think of several possibilities:
A database hook deletes the file.
Business logic deletes the file.
A periodic "job" is run, e.g. by crontab, which trolls through the image directory and queries for each ...
Neither. Better would be not to use file system directly, but to allow database to handle the files as binary fields, or so called BLOBs.
File systems are not transactional. If you use transactions in your logic and some transaction fails, you can be sure that database has rolled back any changes you have done and you have exactly the state ...
On the first request, the server creates a random string for the file, and tells the client. On the subsequent requests, the client sends the same random string back so the server knows it's about the same file.
Exactly the same way S3 works.