Whether the file is "Deleted" from the DB via a UPDATE or a DELETE of a row, the problem is the same -- the database + file operations are not atomic. Neither an UPDATE or a DELETE are safer than the other, they're both transactions in a database whereas the file operation is not.
The solution is that there is never any conflict as to the state of the data. Only one source is considered "the truth" and the other reflects that truth. That way if there's ever an inconsistency between the two, you know what the "truth" is. In fact, there is never a "logical" inconsistency, only the aftermath manifested by physical artifacts on the disk.
In most cases, the Database is a better representation of The Truth.
Here's the truth table:
File Exists -- DB Record exists -- Truth
Yes No File does not exist
Yes Yes File does exist
No Yes File does exist, but its in error.
No No File does not exist
Operationally, here's how this works.
To create a file, copy the file to the final destination, then make an entry in the DB.
If the file copy fails, you don't update the DB.
If the file copy succeeds, but the DB is not updated, the file "does not exist", so back to step one.
If the file copy succeeds and the DB update succeeds, then everything is A-OK
To delete a file, first update the DB to show the file is deleted.
If the DB update succeeds, then delete the actual file.
If the DB update does not, then do not delete the file.
If the file delete fails, no problem -- the file is still "deleted" because the DB says so.
If you follow the work flow, there's "no way" that the file should be missing while the DB says it exists. If the file goes missing, you have an undefined state, that you will need to resolve. But this shouldn't happen barring someone walking on your file system.
The DB transactions help keep things honest.
Occasionally, as Jonathan mentioned, you should run some kind of scavenging, syncing process to make sure there aren't any rogue files. but even then, that's really not an issue save for file space, especially if the file names of the actual files have nothing to do with the original file names. (i.e. they're synthetic files names) That way you don't have to worry about overwrites etc.