Se as chamadas para SP1 seguidas por SP2 forem atômicas, elas devem ser combinadas em T-SQL. Ou perder a transação c#. Você está prolongando a transação desnecessariamente com viagens de ida e volta.
Além disso, por que UPDLOCK no SP1UPDLOCK, mas não no SP1? Não consigo ver por quê. Se o problema for dicas de bloqueio, não as use. Se algo é serializável (por quê?) então, novamente, faça uma única chamada atômica
Observe que o padrão é READ COMMITTED de qualquer maneira
Finalmente, você quer dizer "semáforo" não trava? Usando sp_getapplock controlará o fluxo através do código sem usar bloqueios nos dados