Events 在执行Products.CMFCore.interfaces.iactionSucceedeEvent时进行提升是否将中止工作流的ZODB事务?

Events 在执行Products.CMFCore.interfaces.iactionSucceedeEvent时进行提升是否将中止工作流的ZODB事务?,events,plone,plone-3.x,Events,Plone,Plone 3.x,假设我有mynamespace.myproduct: <subscriber for="..interfaces.myinterface.IMyInterface Products.CMFCore.interfaces.IActionSucceededEvent" handler=".handlers.actionSucceeded" /> <subscriber for="..interfaces

假设我有mynamespace.myproduct

 <subscriber for="..interfaces.myinterface.IMyInterface
                  Products.CMFCore.interfaces.IActionSucceededEvent" 
            handler=".handlers.actionSucceeded" 
    /> 
 <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" 
    /> 
 <subscriber for="..interfaces.myinterface.IMyInterface
                  Products.CMFCore.interfaces.IActionSucceededEvent" 
            handler=".handlers.actionSucceeded" 
    /> 

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

我有一个自定义类型,它有一个自定义工作流。我将使用
doActionFor
从Python执行工作流转换,并在触发
iactionSucceedeEvent
时执行一系列操作


我的问题是:如果我在任何
.handlers.ActionSuccessed
上引发异常,如果发生错误,
doActionFor
调用是否会恢复(即使在运行
IACTIONSucceedEvent
之后)?如果没有,如果我使用
IActionWillBeInvokedEvent
,我是否能够实现我的目标?对于相同的
.interfaces.myinterface.IMyInterface
接口,两个不同的产品都使用
products.CMFCore.interfaces.iactionSucceedeEvent
会有问题吗?

您可以通过将Plone debug level设置为debug(默认值为info)并将日志输出设置为事件处理程序来检查这一点。在调试日志中,Plone打印事务边界

如果在引发异常时,异常导致“505 Internal Server error”,它还将展开任何正在进行的事务(除非手动调用transaction.commit(),但正常代码不应如此)

  • 是的,如果您在某个处理程序中引发任何异常 整个事务将失败,并将恢复
  • 不,您在使用多个订阅服务器时不会遇到问题 相同的接口。他们将按登记顺序执行
  • 不,使用IActionWillBeInvokedEvent不会有帮助。它在wf转换之前触发,但如果引发异常,事务无论如何都会失败

  • 根据@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')
        ...
    

    调试日志记录很有趣,我不知道事务边界。我测试了在事件处理程序中调用
    raise
    ,确实事务被中止了,但我担心我做了一些非常不正常的事情…:/