0
0
Lập trình
Harry Tran
Harry Tran106580903228332612117

Hướng Dẫn Ngăn Chặn 'Race Condition' Trong Laravel Một Cách Hiệu Quả

Đăng vào 1 tuần trước

• 3 phút đọc

Hướng Dẫn Ngăn Chặn 'Race Condition' Trong Laravel Một Cách Hiệu Quả

Chào các bạn, hôm nay mình muốn chia sẻ một vấn đề mà có thể nhiều lập trình viên gặp phải trong quá trình phát triển ứng dụng với Laravel - đó là 'race condition'. Vấn đề này thường xảy ra khi nhiều request giống nhau được gửi đi trong một khoảng thời gian ngắn, dẫn đến việc logic xử lý dữ liệu trở nên sai lệch và không chính xác.

Để giải quyết vấn đề này, có rất nhiều phương pháp khác nhau, nhưng một trong những cách phổ biến nhất là sử dụng Atomic Lock như được nêu trong tài liệu của Laravel. Tuy nhiên, để giúp các bạn dễ dàng hơn trong việc áp dụng, mình đã viết một abstract middleware có thể tái sử dụng lại một cách hiệu quả. Hãy cùng tham khảo nhé!

1. Tạo Abstract Middleware

Trước tiên, chúng ta sẽ tạo ra một lớp abstract middleware cơ bản để xử lý việc ngăn chặn 'race condition'. Dưới đây là mã nguồn mẫu:

php Copy
abstract class AbstractAvoidRaceConditionMiddleware
{
    protected int $timeout = 10;

    /**
     * @throws RaceConditionException
     */
    public function handle(Request $request, Closure $next)
    {
        try {
            $keyLock = $this->keyLock($request);
        } catch (Throwable) {
            return $next($request);
        }

        $lock = Cache::lock($keyLock, $this->timeout);
        if ($lock->get()) {
            $exec = $next($request);
            $lock->release();

            return $exec;
        }

        throw new RaceConditionException($this->messageError());
    }

    abstract protected function keyLock(Request $request): string;

    abstract protected function messageError(): string;
}

2. Sử Dụng Middleware Cho Từng Tình Huống Cụ Thể

Để sử dụng middleware này cho từng tình huống cụ thể, bạn chỉ cần kế thừa từ lớp abstract trên và định nghĩa các phương thức keyLockmessageError như sau:

php Copy
class AvoidRaceConditionWhenApplyMiddleware extends AbstractAvoidRaceConditionMiddleware
{
    protected function keyLock(Request $request): string
    {
        $userId = Auth()->id;
        $jobId = $request->integer('id');
        if ($jobId <= 0) {
            throw new \InvalidArgumentException('Invalid job id when apply job');
        }

        return 'apply_locking_' . $userId . '_' . $jobId;
    }

    protected function messageError(): string
    {
        return 'Bạn đã gửi yêu cầu ứng tuyển quá nhiều lần cho cùng một tin tuyển dụng trong cùng một thời điểm.';
    }
}

3. Giải Thích Cơ Chế Hoạt Động

  • Lớp AbstractAvoidRaceConditionMiddleware giúp tạo ra một logic chung để ngăn chặn 'race condition' bằng cách sử dụng Atomic Lock của Laravel.
  • Các middleware con chỉ cần kế thừa và định nghĩa khóa lock riêng thông qua phương thức keyLock() và thông báo lỗi thông qua phương thức messageError().
  • Khi một request đến, nếu khóa chưa tồn tại, middleware sẽ thực hiện logic bình thường và giải phóng khóa sau khi hoàn tất.
  • Nếu có request khác đến cùng trong khoảng thời gian ngắn (trùng lặp), middleware sẽ báo lỗi để ngăn chặn thao tác lặp lại, từ đó bảo vệ tính toàn vẹn của hệ thống.

🚀 Hy vọng rằng bài viết này sẽ giúp ích cho các bạn trong việc xử lý những thao tác quan trọng và cần thiết cần tránh 'race condition' trong ứng dụng Laravel của mình!
source: viblo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào