Si les appels à SP1 suivis par SP2 sont atomiques, ils doivent être combinés dans T-SQL.Ou perdre la transaction c#. Vous prolongez inutilement la transaction avec des allers-retours.
Aussi, pourquoi avoir UPDLOCK sur SP1UPDLOCK mais pas pour SP1 ? Je ne vois pas pourquoi. Si le problème vient des indices de verrouillage, ne les utilisez pas. Si quelque chose est sérialisable (pourquoi ?), faites-en un seul appel atomique
Notez que la valeur par défaut est READ COMMITTED de toute façon
Enfin, voulez-vous dire "sémaphore" pas verrouiller ? Utilisation de sp_getapplock contrôlera le flux à travers le code sans utiliser de verrous sur les données