事务性消息:在处理完成后处理新消息
编辑本页警告:您正在浏览的文档欧宝官网下载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;使用学说\ORM\EntityManagerInterface;使用ob娱乐下载\组件\信使\信封;使用ob娱乐下载\组件\信使\MessageBusInterface;使用ob娱乐下载\组件\信使\邮票\DispatchAfterCurrentBusStamp;类RegisterUserHandler{私人$eventBus;私人$新兴市场;公共函数__construct(MessageBusInterface$eventBus, 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;使用学说\ORM\EntityManagerInterface;使用ob娱乐下载\组件\梅勒\MailerInterface;使用ob娱乐下载\组件\Mime\RawMessage;类WhenUserRegisteredThenSendWelcomeEmail{私人$梅勒;私人$新兴市场;公共函数__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
中间件必须加载所有正在使用的公共汽车。