Penso che tu stia cercando di risolvere il problema in modo errato. Quello che vuoi è la massima protezione della coerenza del database. Se due persone eseguono una procedura memorizzata contemporaneamente, la coerenza del database potrebbe essere violata.
Per proteggere contro vari tipi di incoerenze del database, lo standard SQL ha quattro livelli di isolamento delle transazioni:
- LEGGI SENZA COMPROMESSI dove sostanzialmente le transazioni perdono il loro valore, altre transazioni vedono dati sporchi. Non usare questo!
- LEGGI IMPEGNATO in cui le transazioni visualizzano solo i dati impegnati, ma potrebbero esserci delle incoerenze in cui due transazioni possono scavalcare le dita dell'altro
- RIPETIBILE LEGGI dove viene risolto un tipo di incoerenza, lettura non ripetibile
- SERIALIZZABILE che garantisce l'esistenza di un ordine virtuale in cui l'esecuzione delle transazioni porterebbe ai risultati che ne derivavano
Tuttavia, lo standard SQL ha un approccio basato sul blocco per queste incoerenze del database e, per motivi di prestazioni, molti database adottano un approccio basato sull'isolamento dello snapshot che sostanzialmente ha questi livelli:
- LEGGI IMPEGNATO che è lo stesso nei database basati sul blocco
- ISOLAMENTO SNAPSHOT in cui il database vede un'istantanea di tutti i dati e se tenta di aggiornare una riga che è stata aggiornata da un'altra transazione, viene annullata, ma ci sono alcune anomalie ben note che possono verificarsi
- SERIALIZZABILE, che è lo stesso dei database basati sul blocco, ma questa volta implementato in modo diverso, non prendendo i blocchi ma assicurando che non vi siano violazioni della serializzazione e, se viene rilevata una tale violazione, annullando una transazione
Le cancellazioni delle transazioni in questi database basati sull'isolamento dello snapshot possono sembrare preoccupanti, ma poi ogni singolo database annullerà una transazione a causa di un deadlock, quindi qualsiasi applicazione ragionevole deve comunque provare di nuovo una transazione.
Quello che vuoi è il livello di isolamento SERIALIZZABILE : assicura che se le transazioni eseguite in modo indipendente una dopo l'altra risultano in un buono stato, anche qualsiasi esecuzione parallela delle transazioni si traduce in un buono stato. Fortunatamente, nella sua tesi di dottorato , Michael Cahill ha scoperto come il livello di isolamento SERIALIZZABILE possa essere supportato da database di snapshot isolati con poco sforzo.
Se si utilizza un livello di isolamento SERIALIZZABILE in un database isolato di istantanee, se due persone provano a eseguire la procedura memorizzata contemporaneamente e si pestano reciprocamente, una delle transazioni verrebbe annullata.
Ora, SQL Server supporta realmente il livello di isolamento SERIALIZABLE (invece di mascherare l'isolamento dello snapshot dietro la parola chiave SERIALIZABLE )? Francamente, non lo so: l'unico database che conosco che lo supporta è PostgreSQL.
Anche se non sono riuscito a fornire consigli specifici su SQL Server, sto comunque pubblicando questa risposta, poiché gli utenti di PostgreSQL e gli utenti di altri database che possono prendere in considerazione il passaggio a PostgreSQL possono trarre vantaggio dalla mia risposta. Inoltre, gli utenti di database non PostgreSQL che non possono passare a PostgreSQL possono fare pressione sul proprio fornitore di database preferito per offrire un livello di isolamento SERIALIZZABILE autentico .