Giao dịch cơ sở dữ liệu là gì và làm thế nào chúng ta có thể triển khai nó trong ứng dụng Laravel?

Sử dụng các giao dịch cơ sở dữ liệu là một cách mạnh mẽ để đảm bảo tính toàn vẹn của dữ liệu. Bạn nhóm nhiều truy vấn cơ sở dữ liệu thành một giao dịch, những truy vấn này sẽ chỉ có hiệu lực nếu tất cả chúng đều thành công. Hãy xem xét đoạn mã sau

$user = User::create[[...]];

Team::create[[
    'owner_id' => $user->id,
    ...
]];

Nếu việc tạo nhóm không thành công, một người dùng sẽ không có nhóm trong hệ thống của bạn. Để ngăn điều này xảy ra, bạn có thể bọc khối bên trong một giao dịch

DB::transaction[function[]{
    $user = User::create[[...]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];

Bây giờ nếu việc tạo nhóm không thành công, toàn bộ giao dịch sẽ bị khôi phục, bao gồm cả truy vấn tạo người dùng. Laravel xử lý mọi thứ đằng sau hậu trường để bạn có thể đảm bảo tính toàn vẹn dữ liệu của mình chỉ bằng một vài dòng mã

Tuy nhiên, các giao dịch cơ sở dữ liệu chỉ bao gồm các truy vấn cơ sở dữ liệu và thực hiện chúng dưới dạng một đơn vị công việc. Bất kỳ mã nào khác mà bạn có thể đưa vào bên trong giao dịch sẽ được thực hiện ngay lập tức và sẽ không đợi sau khi giao dịch được thực hiện

DB::transaction[function[]{
    $user = User::create[[...]];

    Mail::to[$user]->send[new WelcomeEmail[]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];

Trong ví dụ trên, email chào mừng sẽ được gửi tới người dùng ngay cả khi việc tạo nhóm không thành công và hồ sơ người dùng không được lưu trữ trong cơ sở dữ liệu

Một cách khắc phục rõ ràng cho vấn đề này là trích xuất mã gửi thư bên ngoài giao dịch

DB::transaction[function[]{
    $user = User::create[[...]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];

Mail::to[$user]->send[new WelcomeEmail[]];

Bây giờ nếu giao dịch không thành công, một ngoại lệ sẽ được đưa ra và thư sẽ không được gửi. Tuy nhiên, trong nhiều trường hợp, mã chạy xung quanh các truy vấn cơ sở dữ liệu không được gọi trực tiếp. Ví dụ: việc gửi email có thể nằm trong một trình lắng nghe sự kiện

DB::transaction[function[]{
    $user = User::create[[...]];

    Mail::to[$user]->send[new WelcomeEmail[]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
3 kích hoạt sau
DB::transaction[function[]{
    $user = User::create[[...]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
0. Trong trường hợp đó, việc gửi email sẽ diễn ra ngay sau khi người dùng được tạo và trước khi giao dịch được thực hiện

Bắt đầu từ Laravel

DB::transaction[function[]{
    $user = User::create[[...]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
1, bạn có thể bọc bất kỳ mã nào bên trong một bao đóng mà sẽ chỉ được gọi sau khi tất cả các giao dịch đã được thực hiện. Vì vậy, bên trong trình lắng nghe sự kiện gửi email, bạn có thể làm điều này

class SendWelcomeEmail{
    public function handle[]
    {
        DB::afterCommit[function[]{
            Mail::to[$user]->send[new WelcomeEmail[]];
        }];
    }    
}

Bây giờ khi người dùng được tạo và sự kiện được kích hoạt, người nghe sẽ gọi phương thức

DB::transaction[function[]{
    $user = User::create[[...]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
2 sẽ đặt logic gửi thư vào bộ đệm cục bộ và sẽ chỉ thực hiện nó sau khi bất kỳ giao dịch cơ sở dữ liệu nào có thể được mở đã được thực hiện

Nhưng hãy đồng ý, việc phải bọc mã bên trong một bao đóng không làm cho nó trông đẹp hơn chút nào. Vì lý do đó, Laravel giới thiệu một cách khác để đảm bảo các bộ lắng nghe của bạn chỉ được thực thi khi các giao dịch cơ sở dữ liệu đã được cam kết. Hãy lấy người nghe

DB::transaction[function[]{
    $user = User::create[[...]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
3 làm ví dụ

class SendWelcomeEmail{
    public $afterCommit = true;

    public function handle[]
    {
        Mail::to[$user]->send[new WelcomeEmail[]];
    }    
}

Sử dụng thuộc tính

DB::transaction[function[]{
    $user = User::create[[...]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
4, chúng ta có thể hướng dẫn laravel chỉ chạy phương thức
DB::transaction[function[]{
    $user = User::create[[...]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
5 sau khi bất kỳ giao dịch mở nào được cam kết. Nếu không có giao dịch nào được mở, mã sẽ chạy ngay như bình thường

Một tình huống khác mà điều này có ích là gửi một công việc, thư, thông báo, sự kiện được phát hoặc trình nghe được xếp hàng đợi từ bên trong một giao dịch. Công nhân có thể chọn công việc trước khi giao dịch thực hiện và mã sẽ chạy trên trạng thái cơ sở dữ liệu nơi các bản ghi được sửa đổi bởi giao dịch vẫn ở trạng thái cũ. Ví dụ

DB::transaction[function[]{
    $user = User::create[[...]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
2

Công việc

DB::transaction[function[]{
    $user = User::create[[...]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
3 sẽ được gửi đến hàng đợi trước khi giao dịch được thực hiện. Nếu một công nhân chọn nó ngay lập tức, một ngoại lệ
DB::transaction[function[]{
    $user = User::create[[...]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
7 sẽ được đưa ra vì mô hình Người dùng được chuyển cho công việc chưa được lưu trữ trong cơ sở dữ liệu

Đặt thuộc tính

DB::transaction[function[]{
    $user = User::create[[...]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
4 thành true trong lớp công việc sẽ đảm bảo công việc chỉ được gửi đi nếu giao dịch đã được cam kết. Bạn cũng có thể đặt
DB::transaction[function[]{
    $user = User::create[[...]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
9 thành
DB::transaction[function[]{
    $user = User::create[[...]];

    Mail::to[$user]->send[new WelcomeEmail[]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
0 trong cấu hình kết nối hàng đợi bên trong tệp cấu hình
DB::transaction[function[]{
    $user = User::create[[...]];

    Mail::to[$user]->send[new WelcomeEmail[]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
1

DB::transaction[function[]{
    $user = User::create[[...]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
9

Bây giờ tất cả các công việc được gửi qua kết nối hàng đợi

DB::transaction[function[]{
    $user = User::create[[...]];

    Mail::to[$user]->send[new WelcomeEmail[]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
2 sẽ đợi cho đến khi bất kỳ giao dịch mở nào được thực hiện

Ngoài ra, bạn có thể quyết định hành vi trong khi gửi công việc

DB::transaction[function[]{
    $user = User::create[[...]];

    Mail::to[$user]->send[new WelcomeEmail[]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
1

Bạn có thể sử dụng thuộc tính

DB::transaction[function[]{
    $user = User::create[[...]];

    Team::create[[
        'owner_id' => $user->id,
        ...
    ]];
}];
4 trên mailables, notification, jobs, listener, model observers và Broadcasted events

Nếu bạn muốn tìm hiểu thêm về hệ thống hàng đợi của Laravel, hãy đảm bảo kiểm tra Laravel Queues in Action. Tôi đã đặt mọi thứ tôi biết về hệ thống xếp hàng ở định dạng sách điện tử cùng với một số trường hợp sử dụng thực tế. Hãy xem nó để biết khóa học cấp tốc, sách dạy nấu ăn, hướng dẫn và tài liệu tham khảo

Giao dịch cơ sở dữ liệu trong Laravel là gì?

Hãy nói một chút về các giao dịch cơ sở dữ liệu ở nơi đầu tiên. Giao dịch cơ sở dữ liệu là tập hợp các thao tác hoặc truy vấn bạn thực hiện đối với cơ sở dữ liệu mà nó kết hợp và xử lý như một vùng chứa công việc . Điều này có nghĩa là bạn có thể gửi một loạt truy vấn và cơ sở dữ liệu sẽ coi tất cả các truy vấn này là một hành động.

Các giao dịch cơ sở dữ liệu được thực hiện như thế nào?

Các bước trong một giao dịch . Chuyển đĩa khối vào bộ nhớ đệm. Thực hiện cập nhật cho bộ đệm trong bộ đệm. Ghi lại khối đã sửa đổi ra đĩa. Locate the record to be updated from secondary storage. Transfer the block disk into the memory buffer. Make the update to tuple in the buffer buffer. Write the modified block back out to disk.

Giao dịch cơ sở dữ liệu là gì và nó được sử dụng để làm gì?

Một giao dịch thường đại diện cho bất kỳ thay đổi nào trong cơ sở dữ liệu. Giao dịch trong môi trường cơ sở dữ liệu có hai mục đích chính. Để cung cấp các đơn vị công việc đáng tin cậy cho phép khôi phục chính xác sau lỗi và giữ cho cơ sở dữ liệu nhất quán ngay cả trong trường hợp lỗi hệ thống .

Cơ sở dữ liệu nào có thể được sử dụng với Laravel?

Ví dụ cho tất cả các hệ thống cơ sở dữ liệu được hỗ trợ được cung cấp trong tệp này. Hiện tại Laravel hỗ trợ bốn hệ thống cơ sở dữ liệu. MySQL, Postgres, SQLite và SQL Server .

Chủ Đề