Не удается выполнить множественную публикацию внутри transactionScope.

Я смоделировал интеграционную архитектуру между различными подсистемами. Все уведомления от подсистемы отправляются в подписанные подсистемы с использованием примитива Publish. Эти уведомления отправляются в цикле for внутри метода Handler, поэтому все они находятся в одном и том же TransactionScope. Я сделал простой пример, чтобы объяснить это: клиент отправляет сообщение на сервер, который отправляет переменное количество сообщений, используя примитив Publish. Это обработчик сервера:

public void Handle(MyMessage message)
    {

        for (int i = 0; i < message.numberOfNotifications; i++)
        {
            Bus.Publish<NotificationMessage>(m =>
            {
                m.myPersonalCount= i;
            }
            );
        }
    }

Я смотрю и не могу понять, что когда я устанавливаю i на 30 или меньше, все в порядке. От 31 или более я получаю это сообщение об ошибке:

could not execute query
[ SELECT this_.SubscriberEndpoint as y0_ FROM "Subscription" this_ WHERE this_.MessageType in (?) ]

И глядя во внутреннее исключение, я получаю Unable to enlist in a distributed transaction.

Я пробовал то же самое, используя примитив Send, но все было (пробовал с сообщениями 10k), так что это проблема, относящаяся только к директиве Publish.

Я использую Oracle 10g для dbms и Oracle 11g для клиента.

Если конечная точка не является транзакционной, у меня нет никаких проблем, поэтому проблема, похоже, связана только с TransactionScope.

Любая помощь приветствуется, спасибо


person Riccardo    schedule 16.11.2012    source источник
comment
Какую версию NServiceBus вы используете?   -  person Chris Bednarski    schedule 17.11.2012
comment
@ChrisBednarski Я использую версию 2.0.1329.2, я знаю, что это очень старая версия..   -  person Riccardo    schedule 19.11.2012
comment
Я бы предложил перейти на новую версию NSB - аналогично ответу здесь stackoverflow.com/a/12478656/136720   -  person Chris Bednarski    schedule 19.11.2012
comment
Вы включили трассировку Oracle MTS в реестре? Кроме того, существует еще один пул ресурсов для MTS, который может ограничивать вас.   -  person Adam Fyles    schedule 20.11.2012
comment
Да, я включил его, но выглядит нормально, о каком другом пуле ресурсов вы говорите? как я могу это контролировать?   -  person Riccardo    schedule 22.11.2012
comment
Есть пул для подключений и пул для транзакций МТС. Обе шапки можно ставить в реестре. Обратитесь к документации Oracle MTS, чтобы узнать, как включить трассировку в реестре.   -  person Adam Fyles    schedule 25.11.2012


Ответы (1)


Я не являюсь экспертом по Oracle ни в каком смысле. Я, наверное, даже не стал бы новичком.

Однако я знаю, что NServiceBus запрашивает хранилище подписки для каждой отдельной публикации на случай, если между публикациями будут изменения в подписках.

Возможно ли, что клиент Oracle имеет какое-то ограничение на количество запросов, которые могут быть включены в распределенную транзакцию? Возможно, как способ предотвратить проблемы с производительностью типа N + 1?

Тем не менее, кажется очень странным, что вы хотите опубликовать более 30 событий одного и того же типа. Интересно, каков ваш вариант использования в бизнесе. Обычно события должны сообщать о том, что произошло что-то непоправимое. Почему произошло 30 событий?

Если экономическое обоснование является надежным, может быть хорошей идеей реализовать собственный механизм хранения подписки, который использует некоторое ограниченное кэширование (даже 5 секунд), чтобы вы не возвращались к запросу базы данных при каждой отдельной публикации.

person David Boike    schedule 16.11.2012
comment
У меня есть отдельные события, которые могут вызывать до 20 тыс. уведомлений. Я сделал это, потому что моя система должна быть очень масштабируемой, и отправка всех этих небольших сообщений вместо одного с большим количеством данных, по моему мнению, больше подходит для моих ограничений производительности. О чем вы думаете? Однако, если конечная точка не является транзакционной, у меня нет никаких проблем, и поэтому проблема, похоже, связана с контекстом TransactionScope. - person Riccardo; 19.11.2012