Chống "Race Condition" trong Laravel

0 0 0

Người đăng: Bùi Thanh Liêm

Theo Viblo Asia

Có cái này nhỏ nhỏ mà cũng hay hay nên chia sẻ với anh em nè:

Chắc không ít anh em gặp vấn đề liên quan đến "race condition" (không cố tình thì là do click dup, cố tình thì là dùng tool), tức là trong một thời gian ngắn mà nhiều request giống hệt nhau dẫn đến nhiều tình trạng sai logic.

Để chống "race condition", có nhiều cách nhưng phổ biến là dùng Atomic lock (Laravel Docs). Dùng cách này thì không vấn đề gì, nhưng mình có viết một abstract middleware để anh em có thể dùng lại code một cách hiệu quả. Anh em tham khảo nhé:

1. Tạo Abstract Middleware

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 bài toán

Để dùng thằng này thì chỉ cần viết một middleware extend và khai báo keyLock + messageError như sau:

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 'Apply 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

  • AbstractAvoidRaceConditionMiddleware giúp tái sử dụng logic tránh "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 (keyLock()) cũng như thông báo lỗi (messageError()).
  • Khi request tới, nếu khóa chưa tồn tại, nó 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 request bị trùng (chạy song song trong khoảng thời gian ngắn), nó sẽ báo lỗi để tránh thao tác lặp gây ảnh hưởng đến hệ thống.

🚀 Hy vọng sẽ giúp ích cho anh em khi xử lý các thao tác quan trọng cần tránh "race condition"!

Bình luận

Bài viết tương tự

- vừa được xem lúc

Laravel: Middleware SetCacheHeaders

Có rất nhiều middleware hữu ích đã được đăng ký bên trong Laravel, như cơ chế authentication, authorization, throttler và kể cả cơ chế route model binding. Ngoài ra còn có một middleware ít được nhắc đến là SetCacheHeaders, có alias là cache.

0 0 42

- vừa được xem lúc

Cơ bản về Redux Saga

Xin chào tất cả các bạn, bài viết này mình xin chia sẻ một chút kiến thức mình tìm hiểu được về Redux saga, mong mọi người theo dõi. 1) Redux saga là gì.

0 0 102

- vừa được xem lúc

Tổng quan về Middleware - Ứng dụng Middleware trong ASP.NET CORE

1. Khái niệm.

0 0 37

- vừa được xem lúc

Tìm hiểu về Middleware trong Laravel

1.Mở đầu.

0 0 43

- vừa được xem lúc

Blog#29: Tạo một Middleware chuẩn chỉnh trong Nodejs Express - [Express Tutorial - Part 2/10] 😊 (Series: Bí kíp Javascript - PHẦN 24)

Mình là TUẤN hiện đang là một Full-stack Developer tại Tokyo . Tổng quan.

0 0 35

- vừa được xem lúc

Blog#30: Hướng đãn sử dụng Middleware trong Nodejs Express - [Express Tutorial - Part 3/10] 😊 (Series: Bí kíp Javascript - PHẦN 25)

Mình là TUẤN hiện đang là một Full-stack Developer tại Tokyo . Using middleware.

0 0 50