2011-12-08 1 views
0

私はゲームを構築しており、ユーザーは自分の手札やバーチャルバンクの中にお金を持っていると言うことができます!彼らの手からお金を転送し、その逆も私が現在使用している、mysqlとテーブルデータの時間的な問題を克服するには?

if ($_POST['deposit'] > 0 && $_POST['deposit'] <= $user['shrapnel']) { 
    $q = $dbc -> prepare("UPDATE items SET shrapnel = ?, bank = ? WHERE id = ?"); 
    $q -> execute(array($user['shrapnel'] - $_POST['deposit'], $user['bank'] + $_POST['deposit'], $user['id'])); 
} 

また、ユーザーは取引を設定することができ、ユーザーがデに十分なお金を盗む場合、人々は、お互いのオフにお金を盗むことができ

phpが現在のアカウントのif文を検証したが、クエリを完了していない正確な時刻にif文を検証すると、クエリは実行されますが、人々の負担は負の数になり、さまざまな混乱が生じます。

どうすればこの問題を解決できますか?

答えて

0

すべてのテストとSQLをSQLで実行する必要があります。

まず、ユーザーの詳細を取得:

$deposit = $_POST['deposit']; 
$user = $user['id'] 
..... 
$q = $dbc->prepare('CALL DoMoneyStuff(?,?)'); //call to stored proc 
$q->execute(array($deposit, $user)); 
$r = $dbc->prepare('SELECT h.shrapnel, b.amount FROM hand h 
        INNER JOIN Bank b ON (h.user_id = b.user_id) 
        WHERE h.user_id = ?'); 
$q->execute(array($user)); 

はあなたのお金のものを行うために、次のストアドプロシージャを使用してください。
ストアドプロシージャはMySQL上で実行され、ストアドプロシージャ内のすべてのアクションは暗黙のトランザクション内で実行されるため、マネー転送は完全に成功するか完全に失敗します(これはアトミックトランザクションです)。

DELIMITER $$ 

CREATE PROCEDURE DoMoneyStuff(Pdeposit DECIMAL(10,2) 
          ,Puser INTEGER) 
BEGIN 
    DECLARE Pshrapnel DECIMAL(10,2) 

    SELECT Shrapnel INTO PShapnel FROM hand WHERE user_id = Puser LIMIT 1; 
    IF Pshapnel >= Pdeposit THEN 
    UPDATE hand SET Shrapnel = Shrapnel - Pdeposit WHERE user_id Puser; 
    UPDATE bank SET amount = amount + Pdeposit WHERE user_id = Puser; 
    END IF; 
END $$ 

DELIMITER ; 
関連する問題