elegantweb/laravel-transactional-events

该包已被废弃且不再维护。未建议任何替代包。

Laravel 框架的事务性事件。

v2.2.0 2023-04-14 08:56 UTC

This package is auto-updated.

Last update: 2024-08-14 13:23:14 UTC


README

GitHub release (latest by date) GitHub Workflow Status

Laravel 框架的事务性事件。

安装

composer require elegantweb/laravel-transactional-events

为什么?

下面是一个示例

DB::transaction(function () {
    $post = Post::create(['title' => 'An Awesome Post!']);
    event(new PostCreated($post));
    $post->categories()->create(['name' => 'Blog']);
});

乍一看,一切似乎都很正常,但这里有一个大问题!

想象一下,我们在 PostCreated 事件中发送通知,看看会发生什么

情况 1:通知发送失败,可能抛出异常,事务将回滚,创建的帖子将从数据库中删除。实际上发生的情况是,由于通知失败,我们的帖子被删除了。问问自己,“这是我想看到的吗?!🤔”大多数情况下,我们不想因为通知失败而删除帖子!

情况 2:假设 PostCreated 事件成功分派而没有错误。但由于某些数据库或应用程序问题,我们在尝试为我们的帖子创建类别时遇到了错误(多么不幸啊!!! 😩),在这种情况下,事务将失败,帖子将从数据库中删除。到目前为止一切还好,但你知道吗?!我们已经在 PostCreated 事件中为已不存在的帖子发送了通知!😱

解决方案:这里的解决方案是使事件在事务提交后分派。使用这个包,你可以使事件成为事务性的,因此事件将延迟到事务提交时再处理。

用法

该包默认启用。你需要做的是将你的事件变为事务性的。

使用事务接口

使一个事件成为事务性的一种方法是实现 Elegant\Events\TransactionalEvent 接口。下面是一个示例

use Elegant\Events\TransactionalEvent;

class MyAwesomeEvent implements TransactionalEvent
{
}

现在 MyAwesomeEvent 类是事务性的,并且每次你分派它时,它都将由该包处理。

使用配置

另一种方法是使用配置文件。这样,你可以使一组事件成为事务性的。

首先发布默认配置文件

php artisan vendor:publish --tag="laravel-transactional-events-config"

我们有两种选择,includeexclude

使用 include,你可以使某个命名空间下的事件类或事件组成为事务性的。

默认情况下,我们有 App\Events 命名空间,这将导致 App\Events 命名空间下的所有事件都变为事务性的。

return [
    'include' => [
        'App\Events',
    ],
];

exclude 选项与 include 选项相反,你可以排除某个命名空间下的事件类或事件组使其不成为事务性的。

下面的示例将导致 App\Events 命名空间下的所有事件都变为事务性,除了 App\Events\MyAwesomeEvent 类。

return [
    'include' => [
        'App\Events',
    ],

    'exclude' => [
        'App\Events\MyAwesomeEvent',
    ],
];