2011-12-09 16 views
1

ユーザbがユーザaのデータにアクセスしているときに、ユーザbが情報のいくつかを手動で更新し、ユーザBが情報にアクセスすると、ユーザAの古い失効データではなく、 。ユーザーの更新時に、あるユーザーのselectステートメントを確実にするかどうかを確認します。

私はトランザクションが良好で行レベルのロックであることを理解しています。私は正しいことをしていますか?

以上を使用して、

$dbc -> beginTransaction(); 
$dbc -> query("SELECT id FROM accounts WHERE id = " . $user['id'] . " FOR UPDATE LIMIT 1"); 
$q = $dbc -> prepare("UPDATE accounts SET name = ?"); 
$q -> execute(array($_POST['name'])); 
$dbc -> commit(); 

を私は使用しています、ユーザAの情報を更新する場合、ユーザーBが

、使用して、ユーザーのために自分のデータを取得するときように、これは、ユーザAのデータをロックしません
$q = $dbc -> ("SELECT * FROM accounts WHERE id = ?"); 
$q -> execute(array($_GET['id'])); 

彼は正しい更新データを取得しますか?または、ユーザーbのデータを取得するときにトランザクションを使用する必要がありますか?

あなたはおそらく言うことができるように、私は少しこのすべてのロックやもので混乱していますか?

おかげ

+0

行はなります**書き込み*:

参照 は(mysqlはRETURNING句を実装するまで、唯一の欠点は、あなたが同じレコードを再更新したい場合は、データを再クエリする必要があり、それはあります) * - 更新が持続する限りロックされます。 userBは適切なデータを取得できますか?データへのアクセスの瞬間に依存します。同時アクセスとは、「時間が近いので、同時に同じように見える」ということです。 – Alfabravo

+0

ユーザーbのselectステートメントを実行して、行がロックされていないときにのみuser-aの情報を表示する方法はありませんか? – cgwebprojects

+0

userAが既にアップデートを行ったかどうかわからないので、助けにならないでしょうか? – Alfabravo

答えて

0

クライアント&データベースとの間の切断があるウェブサイトに同時実行を処理するために、あなたがそれが以来更新されていない確認することができ、各レコードの列を持っているのが一般的ですあなたは最後にそれを手に入れました。

最終更新日時列または(私の好み)オートインクリメントバージョン番号(トリガーを経由して実装されている)、あなたは、単に値を使用して、レコードなどの値に一致した得たことを、あなたのWHERE句でチェックする必要が次のいずれか

UPDATE accounts SET name = ?, lastupdate=sysdate WHERE id = ? AND lastupdate = ? 

lastupdateの値が一致せず、レコードを更新できない場合は、データが他の誰かによって更新されたとみなして、それに応じて例外を処理することができます。

これは、更新が稀なシステムでうまく機能します。

私は、並行性の値があなたのために維持されるので、トリガーを使用する方が好きです。影響を受けるHandling the concurrent request while persisting in oracle database?