В конечном итоге, учитывая описанные вами ограничения, удаление должно выполняться по одному сообщению за раз - однако при получении сообщения подписчику гораздо больше, чем просто транзакция базы данных (весь код обработки веб-сервиса) , задержка сети и HTTP).
Нынешняя система, очевидно, не очень хорошо реализует управление транзакциями, поэтому я полагаю, что это не проблема и для параллельного решения.
Если бы это был я, я бы настроил хранимую процедуру (почему вы думаете, что они не переносимы?) С операциями в транзакции с сериализуемой блокировкой - я бы также кешировал число сообщений в очереди с помощью TTL основывается на количестве операций / возрасте кэшированного значения, чтобы уменьшить количество дорогостоящих совокупных операций в базовой таблице. Это может быть сделано путем одновременной выдачи DML-операции на языке управления, но общий эффект заключается в том, что операция займет значительно больше времени.
Альтернативный подход (который делает реализацию блокировки более простым) состоял бы в том, чтобы защитить данные - не уверен, что MSSQL поддерживает именованные блокировки - конечно, это не очень переносимое решение - поэтому разбивает данные по отдельным таблицам и использует блокировки таблиц. Это делает реализацию транзакционного контроля намного проще - но есть проблемы с выравниванием нагрузки / последовательной обработкой (но опять же параллельный подход применяет, что последнее не является большой проблемой).