事务性消息:处理后新消息处理完成
编辑该页面事务性消息:处理后新消息处理完成
一个消息处理程序可以调度
新消息在处理其他相同或不同的总线(如果应用程序多个公共汽车)。在这个过程中发生的任何错误或异常可以产生意想不到的后果,如:
- 如果使用
DoctrineTransactionMiddleware
和分派消息抛出一个异常,那么原始处理程序中的任何数据库事务将回滚。 - 如果消息被分配到一个不同的总线,然后分派消息处理即使以后一些代码在当前处理器将抛出一个异常。
一个例子RegisterUser
过程
让我们的应用程序的一个例子命令和一个事件公共汽车。应用程序发出一个命令命名RegisterUser
到命令总线。命令处理的RegisterUserHandler
这创建了一个用户
对象,存储对象到数据库和分派UserRegistered
事件总线消息。
有许多处理程序UserRegistered
消息,一个处理程序可以发送欢迎邮件给新用户。我们使用的是DoctrineTransactionMiddleware
包装在一个数据库事务中所有数据库查询。
问题1:如果抛出一个异常当发送欢迎邮件,然后用户将不会创建,因为DoctrineTransactionMiddleware
将回滚事务原则,创建了用户。
问题2:如果抛出一个异常在保存用户到数据库,待发送邮件仍然是受欢迎的,因为它是异步处理的。
DispatchAfterCurrentBusMiddleware中间件
对于许多应用程序,所需的行为只有派出的处理消息处理程序一旦处理程序已全部完成。这可以通过使用DispatchAfterCurrentBusMiddleware
和添加一个DispatchAfterCurrentBusStamp
邮票消息信封:
1 2 3 4 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
/ / src /通讯/ CommandHandler / RegisterUserHandler.php名称空间应用程序\信使\CommandHandler;使用应用程序\实体\用户;使用应用程序\信使\命令\RegisterUser;使用应用程序\信使\事件\UserRegistered;使用学说\ORM\EntityManagerInterface;使用ob娱乐下载\组件\信使\信封;使用ob娱乐下载\组件\信使\MessageBusInterface;使用ob娱乐下载\组件\信使\邮票\DispatchAfterCurrentBusStamp;类RegisterUserHandler{公共函数__construct(私人MessageBusInterface美元eventBus、私人EntityManagerInterface美元新兴市场,){}公共函数__invoke(RegisterUser美元命令):无效{美元用户=新用户(美元命令- >getUuid (),美元命令- >getName (),美元命令- >getEmail ());美元这- >新兴市场- >persist (美元用户);/ / DispatchAfterCurrentBusStamp标志着事件消息处理/ /只有这个处理程序不抛出异常。美元事件=新UserRegistered (美元命令- >getUuid ());美元这- >eventBus- >调度((新信封(美元事件))- >(新DispatchAfterCurrentBusStamp ()));/ /……}}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21日22日23日24
/ / src /通讯/ EventSubscriber / WhenUserRegisteredThenSendWelcomeEmail.php名称空间应用程序\信使\EventSubscriber;使用应用程序\实体\用户;使用应用程序\信使\事件\UserRegistered;使用学说\ORM\EntityManagerInterface;使用ob娱乐下载\组件\梅勒\MailerInterface;使用ob娱乐下载\组件\Mime\RawMessage;类WhenUserRegisteredThenSendWelcomeEmail{公共函数__construct(私人MailerInterface美元梅勒,EntityManagerInterface美元新兴市场,){}公共函数__invoke(UserRegistered美元事件):无效{美元用户=美元这- >新兴市场- >getRepository(用户::类)- >找到(美元事件- >getUuid ());美元这- >梅勒- >发送(新RawMessage (“欢迎”。美元用户- >getFirstName ()));}}
这意味着UserRegistered
消息才会处理后的RegisterUserHandler
已完成和新吗用户
被持久化到数据库中。如果RegisterUserHandler
遇到一个异常,UserRegistered
事件将不会被处理。如果抛出异常而发送欢迎邮件,教义事务不会被回滚。
请注意
如果WhenUserRegisteredThenSendWelcomeEmail
抛出一个异常,该异常将包裹成一个DelayedMessageHandlingException
。使用DelayedMessageHandlingException: getexception
会给你所有的异常都扔在处理一条消息的吗DispatchAfterCurrentBusStamp
。
的dispatch_after_current_bus
中间件是默认启用。如果你手动配置您的中间件,一定要登记dispatch_after_current_bus
之前doctrine_transaction
在中间件链。此外,dispatch_after_current_bus
中间件必须加载所有公共汽车的使用。