The code you've provided is a text book example of what it takes to make deadlocks. Something is going to need to "give" and you're the one that has to decide that. If it were me, I'd move the delete out of the transaction and, perhaps, setup a sweeper job to clean out the old stuff. If you write your queries to find the newer stuff, it shouldn't cause a problem.