मैं कुछ सवाल ... उदाहरण है: एक उपयोगकर्ता अपने अमरीकी डालरPHP/MySQL - कैसे को रोकने के लिए दो अनुरोध * अद्यतन
- के लिए कुछ खरीद लेंगे उसके अमरीकी डालर शेष
- चेक से अमरीकी डालर काट उसकी खाता
- एक आदेश बनाने -> आदेश कतार
- उपयोगकर्ता अपने आइटम हो जाता है और एक दूसरे को अपने अमरीकी डालर
कहना चलें हो जाता है, उपयोगकर्ता एक ही दूसरे (बहुत तेज़) में 5 अनुरोध करते हैं। तो यह संभव है (और होता है) कि 5 अनुरोध चल रहे हैं। उसके पास केवल 1 अनुरोध से ही खरीदने के लिए धन है। अब अनुरोध इतने तेज़ हैं कि स्क्रिप्ट उसकी शेष राशि की जांच करती है, लेकिन इतनी तेज़ नहीं है कि यह धन को अपने खाते से घटा देती है। तो अनुरोध दो बार गुजरेंगे! इसे कैसे हल करें?
मैं mysql में लॉक का उपयोग करने से पहले मैं इस प्रक्रिया को शुरू:
- IS_FREE_LOCK - जांच इस प्रयोक्ता के लिए एक ताला है अगर नहीं -> 2.
- GET_LOCK - ताला
- बनाने के सेट आदेश/लेन-देन
- RELEASE_LOCK - रिलीज ताला
लेकिन यह वास्तव में काम नहीं करता। क्या कोई और तरीका है?
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));
}
अद्यतन चयन के साथ लेन-देन समारोह परीक्षण किया गया ... अद्यतन
$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();
[** कृपया, नए कोड ** में 'mysql_ *' फ़ंक्शंस का उपयोग न करें **] (http://bit.ly/phpmsql)। वे अब बनाए रखा नहीं जा रहे हैं [और आधिकारिक तौर पर बहिष्कृत हैं] (http://j.mp/XqV7Lp)। [** लाल बॉक्स **] (http://j.mp/Te9zIL) देखें? के बारे में [* तैयार बयान *] जानें (http://j.mp/T9hLWi) के बजाय, और प्रयोग [पीडीओ] (http://php.net/pdo) या [MySQLi] (http://php.net/ mysqli) - [इस अनुच्छेद] (http://j.mp/QEx8IB) आप जो निर्णय लेने में सहायता करेगा। – Kermit
कोई भी जानता है कि इसका क्या अर्थ है: "उपयोगकर्ता उसका आइटम बन जाता है और दूसरा उसका अमरीकी बन जाता है"? क्या उनका मतलब 'बनने' की बजाय 'हो जाता है'? – ESRogs
लेन-देन के बारे में * मूल बातें * जानने के बिना ऑनलाइन ट्रेडिंग साइट को संचालित करने के लिए यह भी संभव है *! – Massimo