2012-03-15 6 views
0

私はpromo_codesというテーブルを持っています。これはWebアプリケーションでアクティブにすることができます。 state列があり、非アクティブ化の場合は0、アクティブ化の場合は1になります。私は1回限りの行シナリオに適したSELECT ... FOR UPDATEはありますか?

SELECT FROM promo_codes WHERE state=0 LIMIT 1 FOR UPDATE; 
UPDATE promo_codes SET state=1 WHERE id = ?; 

でトランザクションを実行すると2番目のトランザクションの実行中に何が起こる:

SELECT FROM promo_codes WHERE state=0 LIMIT 1 FOR UPDATE; 

それは単に次の行を返さない、または最初のトランザクションが完了するまでには、ブロックしていますか?

私は実際にredisの行IDに基づいてロックを設定することについて考え始めました。これは、それがどのように動作するのかが分かりましたが、MySQLではパフォーマンスの問題は発生しません純粋にSQLでこの作業を行うには、きれいで効率的な方法が必要です。たぶん私はちょうどUPDATE ... LIMIT 1を使用することができますが、その場合、どのように私はプロモーションコードのIDを取得するのですか?

答えて

0

UPDATEおよびLOCK IN SHARE MODE修飾子は、現在の分離モードがREPEATABLE-READの場合でも、READ-COMMITTED分離モードで効果的に実行されます。これは、Innodbが行の現在のバージョンのみをロックできるという理由で行われます。同様のケースと行が削除されると考えてください。たとえInnodbがもう存在しない行にロックを設定できたとしても、それはあなたに何か良いことをするでしょうか?実際はそうではありません。たとえば、SELECT FOR UPDATEでロックした行を更新しようとすると、この行はすでに消えてしまいます。とにかくそれは良いためにこのように行われ、他のすべての決定はさらに面倒です。

ロックインシェアモードは実際にはマルチバージョンをバイパスし、最新のデータを読み込み、変更できないようにするためによく使用されます。これは、例えば、一連の行を読み込み、それらの一部の新しい値を計算して書き戻すために使用できます。 LOCK IN SHARE MODEを使用しない場合は、新しい値を書き込む前に行を更新できるため、このような更新が失われる可能性があります。

関連する問題