Seems indeed a cache problem. Looking at the implementation of the Exists method, we can see that it internaly create a new istance of an SPSite object to check if it exist.
SPSite theSite = null;
theSite = new SPSite(uri.OriginalString);
// do nothing, just leave the istance null. The rest of the code will detect this.
After that, some of the property of the istance are evaluated (HostHeaderIsSiteName and some of the url properties).
Problem is that the SPSite costructor utilize an internal cache to set the object properties. Most of the calls seems to come up to the SPSiteCache class and some of its methods (for example: SPSiteCache.LookupHostHeaderSite) => this would mean that if the site is referenced in the cache we can get invalid results.
After some time lost on MSDN I have found some reference to a cache clear method.
SPSite.InvalidateCacheEntry(new Uri(siteCollectionUrl), Guid.Empty);
It seems that this method just calls the SPSiteCache class internaly
public static bool InvalidateCacheEntry(Uri uri, Guid siteId)
return SPSiteCache.InvalidateCacheEntry(uri, siteId);
I have used this istruction just before the call to Exist to ensure a valid result. That way, the problem was resolved.
1) I don't know what is the resource cost of this solution. If performance are critical, please ensure that clearing the cache doesn't bring a performance hit.
2) someone sugested that the problem can be related to the gradual site deletion job. I don't belive it is, but you never know. As I already said, the timer job could as well call the istruction above internally. That said, by calling the InvalidateCacheEntry method I never needed to manually run the job - and I am creating sites pretty fast. Also consider that running a timer job could be problematic in some context - so give the above method a try if you are experiencing the same problem.