2011-11-16 8 views
0

ここでは簡単な質問/説明が必要です。私はかなりの可能性のあるレコードを同時に更新するDBテーブルを持っています。私はアプリケーションのためにZend Frameworkを使用していますが、これを避けるためには2つの方向について読んでいます。最初にテーブルをロックする(LOCK TABLES WRITE)かそのようなものが戻ってきて、それが最善の解決策です。 2番目はトランザクションです:$ db-> beginTransaction(); ... $ db-> commit();MySQLトランザクション対ロック

「InnoDBのようなトランザクション型ストレージエンジンを使用していると仮定すると、トランザクションはより一般的なソリューションのように思えます。しかし、それは次のような状況を避けるん:

ユーザAは、Webページ上にある - >は、データを提出 - >トランザクションを開始 - >読ん行 - >新しい値を計算 - >更新行 - >保存 - >

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

IE:データベース行の

開度値:5ユーザーAが( トランザクションを開始し5の値を提出 - >読み取り値(5) - >送信された値(5 + 5 = 10を追加) - の値が0であることを確認する必要があります(更新が行われた場合、更新された値 - >保存 - >コミット) の値が10であることを確認する必要があります。読み込み前に を実行していません)。

私はこれが長らく説明されていることを知っています。私は謝ります。問題を簡略化するための正しい用語が正確にはわかりません。

ありがとうございました

+1

あなたは 'UPDATE table SET value = value + 5'のようなことをやり遂げることができますか?その後、取引は必要ありません。 –

+0

それは働くことができ、私の人生を楽にしてくれるでしょう。私が*遭遇する可能性のある問題は1つだけです。私は更新を行い、次に値を読み取る前に2番目のセッションが更新され、正しい値を元のユーザーに送り返す必要があります。したがって、現在の '値'を取得するための更新と選択が行われます。読み込みが行われる前に2回目の更新が行われるのが嫌な場合、返された結果は無効になります(または間違っています)。私の懸念の理由は、データが更新されてユーザーに返されたときに、データが100%保証されている必要があるからです。 –

+0

私はあなたが100%正しいことができるとは思わない。たとえ正しい値が読み取られたとしても、それをユーザーに送信してロックを解放した瞬間であっても、期限切れになっている可能性があります。リアルタイムのデータベース更新を受け取るイベント駆動型システムを持たない限り、現在の値を保証することはできません。 (それでも、目に見える遅れがあるかもしれません。) –

答えて

0

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

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

Transaction do 
row.lock 
update row 
end 

を参照してください。行レベルのロックを使用すると、

+0

私はこの答えを純粋にそれが私のオリジナルに答えたという事実に基づいて受け入れるつもりです(クイックバージョン)の質問は「取引は競争条件から保護されます」と答えはノーです。 @MichaelMiorのコメントは、私の問題を別の観点から見て、より実行可能な解決策を提供するのに役立ったと思います。両方とも/ありがとう! –

関連する問題