Tôi có một số câu hỏi ... dụ: người dùng sẽ mua một cái gì đó cho mìnhPHP/MySQL - làm thế nào để ngăn chặn hai yêu cầu * Cập nhật
- USD Trả USD Balance mình
- việc khấu trừ, USD từ ông tài khoản
- Hãy lệnh -> trật tự xếp hàng
- dùng được item của mình và một trong những khác được ông
USD Cho phép nói, người dùng thực hiện 5 yêu cầu trong cùng một giây (rất nhanh). Vì vậy, có thể (và xảy ra) 5 yêu cầu đang chạy. Anh ta chỉ có tiền để mua chỉ từ 1 yêu cầu. Bây giờ các yêu cầu quá nhanh, tập lệnh sẽ kiểm tra số dư của anh ấy, nhưng không quá nhanh, để trừ số tiền từ tài khoản của anh ấy. Vì vậy, các yêu cầu sẽ vượt qua hai lần! Cách giải quyết?
tôi sử dụng KHÓA trong mysql trước khi tôi bắt đầu quá trình:
- IS_FREE_LOCK - kiểm tra là có một khóa cho người dùng này nếu không muốn nói -> 2.
- GET_LOCK - bộ khóa
- làm cho đơn hàng/giao dịch
- RELEASE_LOCK - giải phóng khóa
Nhưng điều này không thực sự hiệu quả. Có cách nào khác không?
function lock($id) {
mysql_query("SELECT GET_LOCK('$id', 60) AS 'GetLock'");
}
function is_free($id) {
$query = mysql_query("SELECT IS_FREE_LOCK('$id') AS 'free'");
$row = mysql_fetch_assoc($query);
if($row['free']) {
return true;
} else {
return false;
}
}
function release_lock($id) {
mysql_query("SELECT RELEASE_LOCK('$id')");
}
function account_balance($id) {
$stmt = $db->prepare("SELECT USD FROM bitcoin_user_n WHERE id = ?");
$stmt->execute(array($id));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
return $row['USD'];
}
if(is_free(get_user_id())) {
lock(get_user_id());
if(account_balance(get_user_id()) < str2num($_POST['amount'])) {
echo "error, not enough money";
} else {
$stmt = $db->prepare("UPDATE user SET USD = USD - ? WHERE id = ?");
$stmt->execute(array(str2num($_POST['amount']), get_user_id()));
$stmt = $db->prepare("INSERT INTO offer (user_id, type, price, amount) VALUES (?, ?, ?, ?)");
$stmt->execute(array(get_user_id(), 2, str2num($_POST['amount']), 0));
}
Cập nhật Tested chức năng giao dịch với SELECT ... FOR UPDATE
$db->beginTransaction();
$stmt = $db->prepare("SELECT value, id2 FROM test WHERE id = ? FOR UPDATE");
$stmt->execute(array(1));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if($row['value'] > 1) {
sleep(5);
$stmt = $db->prepare('UPDATE test SET value = value - 5 WHERE id = 1');
$stmt->execute();
$stmt = $db->prepare('UPDATE test SET value = value + 5 WHERE id = 2');
$stmt->execute();
echo "did have enough money";
} else {
echo "no money";
}
$db->commit();
[** Vui lòng không sử dụng các hàm 'mysql_ *' trong mã mới **] (http://bit.ly/phpmsql). Chúng không còn được duy trì [và được chính thức ngừng sử dụng] (http://j.mp/XqV7Lp). Xem [** hộp màu đỏ **] (http://j.mp/Te9zIL)? Tìm hiểu về [* statement statements *] (http://j.mp/T9hLWi) thay vào đó, và sử dụng [PDO] (http://php.net/pdo) hoặc [MySQLi] (http://php.net/ mysqli) - [bài viết này] (http://j.mp/QEx8IB) sẽ giúp bạn quyết định cái nào. – Kermit
Bất kỳ ai biết điều này có nghĩa là: "người dùng trở thành vật phẩm của anh ấy và người kia trở thành đô la của anh ấy"? Chúng có nghĩa là 'được' thay vì 'trở thành'? – ESRogs
Làm thế nào là nó thậm chí có thể * để vận hành một trang web giao dịch trực tuyến mà không biết ngay cả những khái niệm cơ bản * về giao dịch?!? – Massimo