在Laravel框架中使用数据库事务及案例demo

2023-06-01 00:00:00 事务 框架 案例

在我们开始研究 Laravel 的数据库事务之前,让我们先看看它们是什么以及它们如何有益。

对于什么是数据库事务,有许多听起来复杂的技术解释。

但是,对于大多数 web 开发人员来说,我们只需要知道事务是完成数据库中整个工作单元的方式。

换句话说,它 “要么全有,要么全没有”。


事务案例demo

需求描述:

假设我们有一个允许用户注册的应用程序。

每当用户注册时,我们都希望为他们创建一个新帐户,然后为他们分配一个默认角色 “general”。


在 Laravel 中使用数据库事务

现在我们对事务是什么以及它们实现了什么有了一个简单的概念,让我们来看看如何在 Laravel 中使用它们。

在 Laravel 中,由于我们可以在 DB 门面上访问 transaction() 方法,因此开始使用事务实际上是很容易的事。

根据需求描述,让我们看看在创建用户并为其分配角色时如何使用事务:

use Illuminate\Support\Facades\DB;

DB::transaction(function () use ($user, $request): void {
    $user = User::create([
        'email' => $request->email,
    ]);
   
    $user->roles()->attach(Role::where('name', 'general')->first());
});

现在我们的代码被包裹在一个数据库事务中,如果在其中的任意一点抛出异常,对数据库的任何更改都将返回到事务开始之前的状态。


在 Laravel 中使用自动或手动事务

同样值得注意的是,因为我们最初的示例使用 DB:transaction() 方法,在抛出异常时回滚事务,所以我们也可以使用这种方法向我们的第三方服务发出请求。

相反,我们可以这样更新类:

use Illuminate\Support\Facades\DB;
use App\Services\ThirdPartyService;

DB::transaction(function () use ($user, $request): void {
    $user = User::create([
        'email' => $request->email,
    ]);
   
    $user->roles()->attach(Role::where('name', 'general')->first());
   
    if (! $thirdPartyService->createUser($userData)) {
        throw new \Exception('User could not be created');
    }
});

这绝对是一个可行的解决方案,并将按照预期成功回滚事务。

事实上,就我个人的偏好而言,我实际上更喜欢这种方式,而不是手动使用事务。

我认为它看起来更容易阅读和理解。


然而,与手动提交或回滚事务时使用 'if' 语句相比,异常处理在时间和性能方面可能会比较昂贵。

因此,举个例子:

如果这段代码用于导入包含 10,000 个用户数据的 CSV 文件,您可能会发现抛出异常会大大减慢导入速度。


但是,如果它只是在一个用户可以注册的简单 web 请求中使用,那么抛出异常可能没有问题。

当然,这取决于应用程序的大小,性能是关键因素;

所以你需要根据具体情况来决定。

相关文章