Выполнение повышения во время выполнения Products.CMFCore.interfaces.IActionSucceededEvent собирается прервать транзакцию ZODB для рабочего процесса? - PullRequest
2 голосов
/ 06 сентября 2011

Предположим, у меня есть mynamespace.myproduct :

 <subscriber for="..interfaces.myinterface.IMyInterface
                  Products.CMFCore.interfaces.IActionSucceededEvent" 
            handler=".handlers.actionSucceeded" 
    /> 

и mynamespace.myproduct2 :

 <subscriber for="..interfaces.myinterface.IMyInterface
                  Products.CMFCore.interfaces.IActionSucceededEvent" 
            handler=".handlers.actionSucceeded" 
    /> 

(обработчики делают разные вещи для каждого продукта, даже если в этом примере они имеют одинаковые имена)

У меня есть пользовательский тип, который имеет собственный рабочий процесс. Я собираюсь сделать переход рабочего процесса из Python, используя doActionFor, и делать кучу вещей, когда IActionSucceededEvent запускается.

Мой вопрос: если я вызову исключение для любого из .handlers.actionSucceeded, если произойдет ошибка, будет ли doActionFor вызов отменен (даже после запуска IActionSucceededEvent)? Если нет, если я использую IActionWillBeInvokedEvent, смогу ли я достичь своих целей? Будет ли у меня проблема с двумя разными продуктами, использующими Products.CMFCore.interfaces.IActionSucceededEvent для одного и того же ..interfaces.myinterface.IMyInterface интерфейса?

Ответы [ 3 ]

4 голосов
/ 06 сентября 2011
  1. Да, если вы вызовете какое-либо исключение в одном из ваших обработчиков, вся транзакция завершится неудачно и будет отменена
  2. нет, у вас не возникнет проблем с использованием более одного подписчика для одного и того жеинтерфейсы.Они будут выполняться в порядке регистрации.
  3. нет, использование IActionWillBeInvokedEvent не поможет.Он запускается до перехода wf, но если вы вызовете исключения, транзакция все равно будет неудачной.
3 голосов
/ 06 сентября 2011

Согласно ответу @ Giacomo, транзакция будет прервана для любого не обнаруженного исключения. Поэтому лучше всего выяснить, какие ошибки вы хотите допустить, и поймать эти исключения у вашего подписчика, записать исключение , а затем двигаться дальше, чтобы транзакция все еще была зафиксирована:

import logging
logger = logging.getLogger('mynamespace.myproduct')
...
def actionSucceeded(obj, event):
    ...
    try:
        my_dangerous_stuff(...)
    except (TolerableException, AnotherTolerableException, ...):
        logger.exception('Encountered an error while handling foo event')
    ...
3 голосов
/ 06 сентября 2011

Вы можете проверить это, установив уровень отладки Plone в DEBUG (по умолчанию это информация) и поместив выходные данные журнала в обработчики событий. В журнале отладки Plone печатает границы транзакций.

Если ваше исключение вызывает «505 Внутренняя ошибка сервера», когда возникает исключение, оно также будет развертывать любую текущую транзакцию (если не транзакция exchange.commit () вызвана вручную, но это не должно иметь место для нормального кода) ,

...