加入收藏 | 设为首页 | 会员中心 | 我要投稿 武汉站长网 (https://www.027zz.cn/)- 云连接、智能边缘云、数据快递、云手机、云日志!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

什么是数据库事务

发布时间:2023-12-25 22:36:35 所属栏目:PHP教程 来源:DaWei
导读: 在这篇文章中我们来了解一下“什么是数据库事务,Laravel项目中如何用”,一些朋友可能会遇到这方面的问题,对此在下文小编向大家来讲解,内容详细,易于理解,希望大家阅读完这篇
在这篇文章中我们来了解一下“什么是数据库事务,Laravel项目中如何用”,一些朋友可能会遇到这方面的问题,对此在下文小编向大家来讲解,内容详细,易于理解,希望大家阅读完这篇能有收获哦,有需要的朋友就往下看吧!

在本文中,我们将看看什么是数据库事务,为什么它们很重要,以及如何在 Laravel 开始使用它们。我们还将研究一个常见的“问题”,涉及队列和数据库事务。

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

对于什么是数据库事务,有许多听起来复杂的技术解释。但是,对于大多数 web 开发人员来说,我们只需要知道事务是完成数据库中整个工作单元的方式。

为了理解这实际上意味着什么,让我们来看一个基本的例子,它将给出一点上下文。

假设我们有一个允许用户注册的应用程序。每当用户注册时,我们都希望为他们创建一个新帐户,然后为他们分配一个默认角色“ general”。

我们的代码可能是这样的:

$user = User::create([
    'email' => $request->email,
]);

$user->roles()->attach(Role::where('name', 'general')->first());登录后复制

乍一看,这段代码似乎完全没问题。但是,当我们仔细观察的时候,我们可以发现实际上有一些事情可能会出错。我们可以创建用户,但是不能为他们分配角色。这可能是由许多不同的原因造成的,比如分配角色的代码中的错误,或者甚至是阻止我们到达数据库的硬件问题。

由于这种情况的发生,这将意味着系统中将有一个没有角色的用户。正如您可以想象的那样,这可能会在您的应用程序中的其他地方引起异常和 bug,因为您总是假设用户有一个角色(这是正确的)。

因此,为了解决这个问题,我们可以使用数据库事务。通过使用事务,它可以确保在执行代码时,如果出现任何错误,事务内部对数据库的任何更改都将回滚。例如,如果用户被插入到数据库中,但是由于任何原因分配角色的查询失败,那么事务将被回滚,用户行将被删除。通过这样做,它意味着我们不能创建没有分配角色的用户。

在 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 中手动使用数据库事务

有时,您可能希望对事务进行更精细的控制。例如,假设您正在与第三方服务集成,比如 Mailchinp 或 Xero。我们会说,每当您创建一个新用户时,您还需要向他们的 API 发出 HTTP 请求,以将他们也创建为该系统中的用户。

我们可能想要更新我们的代码,以便如果我们无法在我们自己的系统 ** 且 ** 在第三方系统中创建用户,则两个系统都不创建用户。 如果您正在与第三方系统交互,那么您可能有一个可用于发出请求的类。 或者,可能有一个您可以使用的包。 有时,当某些请求无法完成时,发出请求的类可能会抛出异常。 然而,其中一些类可能会消除错误,而只是从您调用的方法中返回 false,并将错误放置在类的字段中。

因此,我们假设我们有以下调用 API 的基本示例类:

class ThirdPartyService
{
    private $errors;

    public function createUser($userData)
    {
        $request = $this->makeRequest($userData);

        if ($request->successful()) {
            return $request->body();
        }

        $errors = $request->errors();

        return false;
    }

    public function getErrors()
    {
        return $this->errors;
    }
}登录后复制

当然,上面的请求类代码是不完整的,我下面的代码示例也不是很清楚,但它应该能让您大致了解我要表达的观点。所以让我们使用这个请求类并将其添加到我们之前的代码示例中:

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

DB::beginTransaction();

$thirdPartyService = new ThirdPartyService();

$userData = [
    'email' => $request->email,
];

$user = User::create($userData);

$user->roles()->attach(Role::where('name', 'general')->first());

if ($thirdPartyService->createUser($userData)) {
    DB::commit();

    return;
}

DB::rollBack();

report($thirdPartyService->getErrors());登录后复制

查看上面的代码,我们可以看到我们启动了一个事务,创建了用户并为他们分配了一个角色,然后我们调用了第三方服务。如果在外部服务中成功创建了用户,知道所有内容都已正确创建,我们就可以安全地提交数据库更改。但是,如果没有在外部服务中创建用户,则回滚数据库中的更改(删除用户及其角色分配),然后报告错误。

(编辑:武汉站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章