0

ここで簡単な質問/説明が必要です。レコードが同時に更新される可能性が非常に高い DB テーブルがあります。私はアプリケーションに Zend Framework を使用しています。これを回避するための 2 つの方向性について読みました。それが最善の解決策です。2 番目はトランザクションです: $db->beginTransaction(); ... $db->commit();

ここで、InnoDB などのトランザクション ストレージ エンジンを使用していると仮定すると、トランザクションがより一般的なソリューションのように思えます。ただし、次のシナリオは回避できますか。

ユーザー A が Web ページ上にいる -> データを送信する -> トランザクションを開始する -> 行を読み取る -> 新しい値を計算する -> 行を更新する -> 保存する -> コミットする

ユーザー B は同時に同じ Web ページにいて、同時にデータを送信します。ここでは、ほぼ同時であるとしましょう (ユーザー B は、ユーザー A のトランザクションのトランザクションの開始とコミットの間の時点で更新関数を呼び出します)。レコードを更新するための正確な計算を達成する前に、ユーザー A のトランザクションからコミットされたデータに対して。

いいえ:

データベース行の開始値: 5 ユーザー A が値 5 を送信します。 (トランザクションの開始 -> 値 (5) の読み取り -> 送信された値の追加 (5+5=10) -> 更新された値の書き込み -> 保存 -> コミット)

ユーザー B は値 7 を送信します。ユーザー B のトランザクション読み取り値が 5 ではなく 10 であることを確認する必要があります (読み取り前に更新が行われていない場合)。

これは長々とした説明であることは承知しています。申し訳ありませんが、質問を単純化するための正しい用語が正確にはわかりません。

ありがとう

4

1 に答える 1

1

トランザクションはロックを保証しません。トランザクション内のブロック全体は、dbへのアトミック更新として扱われます(このブロックの以前のすべての変更の間に何かが失敗した場合は、ロールバックされます)。したがって、並行して実行されている2つのトランザクションは、同じ行を更新できます。

両方を使用する必要があります。

Transaction do
 row.lock
 update row
end

行レベルのロックによってuが簡単になるかどうかを確認してください。

于 2011-11-16T05:45:25.080 に答える