事务性消息:在处理完成后处理新消息

编辑本页

警告:您正在浏览的文档欧宝官网下载appob娱乐下载Symfony 5.0,现已不再维护。

本页的更新版本用于Syob娱乐下载mfony 6.2(当前稳定版本)。

事务性消息:在处理完成后处理新消息

消息处理程序可以调度执行期间的新消息,发送到相同或不同的总线(如果应用程序有多个公共汽车).在此过程中发生的任何错误或异常都可能产生意想不到的后果,例如:

  • 如果使用DoctrineTransactionMiddleware被分派的消息抛出异常,那么原始处理程序中的任何数据库事务都将回滚。
  • 如果消息被分派到不同的总线,那么即使当前处理程序中稍后的某些代码抛出异常,也将处理分派的消息。

一个例子RegisterUser过程

让我们举一个应用程序的例子命令和一个事件公共汽车。应用程序分派一个名为RegisterUser到命令总线。命令由RegisterUserHandler这就创建了用户对象,将该对象存储到数据库中,并分发一个UserRegistered发送到事件总线的消息。

的处理程序有很多UserRegistered消息,一个处理程序可以向新用户发送欢迎电子邮件。我们用的是DoctrineTransactionMiddleware将所有数据库查询包装在一个数据库事务中。

问题1:如果在发送欢迎电子邮件时抛出异常,则不会创建用户,因为DoctrineTransactionMiddleware将回滚Doctrine事务,在该事务中已经创建了用户。

问题2:如果在将用户保存到数据库时抛出异常,则仍然会发送欢迎电子邮件,因为它是异步处理的。

DispatchAfterCurrentBusMiddleware中间件

对于许多应用程序,期望的行为是只有处理程序完全完成后,处理由处理程序分派的消息。这可以通过使用DispatchAfterCurrentBusMiddleware加上一个DispatchAfterCurrentBusStamp邮票信息信封

12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
名称空间应用程序信使CommandHandler使用应用程序实体用户使用应用程序信使命令RegisterUser使用应用程序信使事件UserRegistered使用学说ORMEntityManagerInterface使用ob娱乐下载组件信使信封使用ob娱乐下载组件信使MessageBusInterface使用ob娱乐下载组件信使邮票DispatchAfterCurrentBusStampRegisterUserHandler私人eventBus私人新兴市场公共函数__construct(MessageBusInterfaceeventBus, EntityManagerInterface新兴市场->eventBus =eventBus->em =新兴市场;}公共函数__invoke(RegisterUser命令用户用户(命令->getUuid (),命令->getName (),命令->getEmail ());->新兴市场->persist (用户);// DispatchAfterCurrentBusStamp标记要处理的事件消息//如果该处理程序不抛出异常。事件UserRegistered (命令->getUuid ());->eventBus->调度((信封(事件))->(DispatchAfterCurrentBusStamp ()));/ /……}}
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
名称空间应用程序信使EventSubscriber使用应用程序实体用户使用应用程序信使事件UserRegistered使用学说ORMEntityManagerInterface使用ob娱乐下载组件梅勒MailerInterface使用ob娱乐下载组件MimeRawMessageWhenUserRegisteredThenSendWelcomeEmail私人梅勒私人新兴市场公共函数__construct(MailerInterface梅勒, EntityManagerInterface新兴市场->梅勒=梅勒->em =新兴市场;}公共函数__invoke(UserRegistered事件用户->新兴市场->getRepository(用户::类)->找到(事件->getUuid ());->梅勒->发送(RawMessage (“欢迎”用户->getFirstName ()));}}

这意味着UserRegistered消息将直到RegisterUserHandler已经完成的和新的用户被持久化到数据库。如果RegisterUserHandler遇到异常时,则UserRegistered事件永远不会被处理。如果在发送欢迎电子邮件时抛出异常,Doctrine事务将不会回滚。

请注意

如果WhenUserRegisteredThenSendWelcomeEmail抛出异常,则该异常将被包装为DelayedMessageHandlingException.使用DelayedMessageHandlingException: getexception方法传递消息时抛出的所有异常都会显示给您DispatchAfterCurrentBusStamp

dispatch_after_current_bus默认情况下启用中间件。如果您手动配置中间件,请确保注册dispatch_after_current_bus之前doctrine_transaction在中间件链中。此外,dispatch_after_current_bus中间件必须加载所有正在使用的公共汽车。

此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。