正在执行Products.CMFCore.interfaces.IActionSucceededEvent时执行加注将中止工作流的ZODB事务?

时间:2011-09-05 20:48:01

标签: events plone plone-3.x

假设我有 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" 
    /> 

(处理程序对每个产品执行不同的操作,即使它们在此示例中具有相同的名称)

我有一个具有自定义工作流程的自定义类型。我将使用doActionFor从Python进行工作流转换,并在触发IActionSucceededEvent时执行一些操作。

我的问题是:如果我发现错误.handlers.actionSucceeded,如果发生错误,doActionFor调用是否会被恢复(即使在IActionSucceededEvent运行后)?如果没有,如果我使用IActionWillBeInvokedEvent,我能否实现目标?对于同一个Products.CMFCore.interfaces.IActionSucceededEvent界面使用..interfaces.myinterface.IMyInterface,我会遇到两个不同产品的问题吗?

3 个答案:

答案 0 :(得分:4)

  1. 是的,如果您在其中一个处理程序中引发任何异常,那么 整个交易将失败并将被还原
  2. 不,您在使用多个订阅者时不会遇到问题 相同的接口。它们将按照注册顺序执行。
  3. 不,使用IActionWillBeInvokedEvent无济于事。它在转换之前被解雇了,但如果你提出异常,交易将无论如何都会失败。

答案 1 :(得分:3)

您可以通过将Plone调试级别转换为DEBUG(默认为info)来检查这一点,并将日志记录输出放入事件处理程序。在DEBUG日志记录中,Plone打印事务边界。

如果异常引发“505内部服务器错误”,它还会展开任何正在进行的事务(除非手动调用transaction.commit(),但普通代码不应该这样) 。

答案 2 :(得分:3)

根据@ Giacomo的回复,对于未捕获的任何异常,交易将被中止。因此,最好的办法是找出您想要容忍的错误并在订阅者log the exception中捕获这些异常,然后继续进行,以便仍然提交交易:

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')
    ...