Yêu cầu thg 3 28, 2021 7:08 SA 156 0 5
  • 156 0 5
0

[Laravel] xử lý dữ liệu cùng một thời điểm

Chia sẻ
  • 156 0 5

Mình có 1 hàm rut tiền khi trong tài khoản có tiền như này ( hàm ruttien) Người A tiền hành rút tiền.

function rutien(Resquest  $r){
$a = NhanVien::where('id',$r->ID)->first();
	$luong = $a->luong;
	if($luong>0){
		$daily->decrement('luong',$luong);   
}

Nhưng cùng tại thời điểm đó thì người B, tiến hành hàm gửi tiền cho người A

function tangdiem( Resquest  $r){

$b = NhanVien::where('id',$r->id)->first();
$sotien = 100; 
$b->increment('luong',$sotien);   
}

Lỗi của mình gặp phải là nếu A và B làm 2 thời gian lệch nhau thì ok, ngon lành không vấn đề gì, nhưng nếu cả hai cùng làm 1 thời điểm thì nó gặp phải lỗi hieur sai vấn đề, có nghĩa hàm rút tiền nó sẽ trừ nhiều hơn số tiền hiện có, làm cho số tiền của người A sau khi rút sẽ bị âm xuống.

Không hiểu mình bị sai chỗ nào mà gây ra chuyện này nhỉ, và có thể cho mình phương án xử lý . Thanks All.

5 CÂU TRẢ LỜI


Đã trả lời thg 3 28, 2021 11:12 SA
0

Cái hàm so sánh kia thì ăn thua gì thím.

ví dụ số dư là 20k, 2 lệnh rút tiền cùng lúc thì phép so sánh >0 đều pass thôi 😄

Làm cho cái hàm rút tiền đó chạy tuần tự (lock chỉ có 1 process chạy hàm này vào 1 thời điểm: cho vào queue rồi dùng 1 chạy chẳng hạn)

Chia sẻ
Avatar TinhTN @tinhtn89
thg 3 28, 2021 4:10 CH

Mình hiểu ý bạn, nhưng có thể nói rõ hơn làm sao để biết cái nào đang chạy , để lock 1 cái chạy 1 cái .

Đã trả lời thg 3 29, 2021 3:44 SA
0

@tinhtn89 Bạn thử đối ứng nó bằng queue nhé.
Tham khảo doc: https://laravel.com/docs/8.x/queues#introduction
Thay vì request rút tiền đến, bạn sẽ xử lý cho phép rút tiền ngay.
Thì bạn dispatch 1 lệnh rút tiền vào trong queue.
Tương tự với hàm gửi tiền cũng thế.
Queue giúp bạn đảm bảo được, mỗi thời điểm chỉ có 1 job rút tiền hay gửi tiền đc chạy.

Tiện thể bạn đặt tên hàm là tăng điểm à 😄 tangdiem
Cố gắng đặt lên dễ hiểu xíu nữa nhé.

Chia sẻ
Avatar TinhTN @tinhtn89
thg 3 29, 2021 5:23 SA

Cảm ơn bạn, Mình viết tên hàm đó cho ae dễ hiểu thôi, tangdiem = tặng điểm 😃 Về cơ chế thì mình hiểu nhưng vẫn chưa biết cách viết như nào?

Avatar iamfresher @benkyou
thg 3 29, 2021 6:12 SA

@tinhtn89 Bạn cứ lấy hướng dẫn gửi mail này làm ví dụ này.
https://rathorji.in/p/laravel_76_queue_tutorial_laravel_76_send_mail_with_queue_example Thì bài toán trên của bạn cũng tương tự như vậy.
Nói queue sang miệng thế thôi, thực ra nó tạo trong db của bạn thêm 1 bảng, để đăng ký các job vào đó.
Sau đó cứ xử lý xong thì nó xóa đi.
Rồi tìm tới record tiếp theo để xử lý.

Đã trả lời thg 3 30, 2021 1:29 SA
0

Theo mình bạn nên tìm hiểu thêm về transaction db và queue. giả sử trong trường hợp hết điện ở cái đoạn trừ tiền thì sao

Chia sẻ
Đã trả lời thg 4 1, 2021 9:35 SA
0

Bạn tìm hiểu thằng này thử xem https://laravel.com/docs/8.x/queries#pessimistic-locking Ý tưởng là lock bản ghi lại, cho đến khi process khác xử lý xong

Chia sẻ
Đã trả lời thg 4 5, 2021 9:28 SA
0
  1. đây là bài toán transaction nên dùng các database có cơ chế lock khi update/insert, ví dụ như mysql
  2. sử dụng cơ chế lock database để xử lí, bạn tham khảo bài này xem: https://viblo.asia/p/mysql-table-locking-yMnKMjjaZ7P
Chia sẻ
Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí