1

私のアプリケーションでは、データの書き込み要求が来るとすぐに、データベースへの挿入を実行したいと考えています。

InnoDB エンジンを使用しています。

挿入には排他ロックが必要なため、現在の読み取りクエリが共有ロックを持っている間に、他の読み取りが再び共有ロックを持ち、書き込み操作が長時間待たなければならない可能性があります。

キューに書き込み操作がある場合、読み取り操作が共有ロックを取得しないようにします。現在の書き込み要求の前に開始された読み取りが完了するとすぐに、書き込み操作を実行する必要があります。その後、他のすべての読み取り操作が行われます。

これはどのように実装できますか?

編集

私は InnoDB テーブルを使用しており、テーブル ロックを実装していないため、選択と挿入の間に競合が発生することはありません。選択して更新します。(selectとinsertの間にも競合がある可能性がある場合は修正してください)

MySQL では、更新は選択より優先されます。ただし、いくつかの読み取りクエリが実行されている場合は、更新クエリが続き、いくつかの読み取りクエリが続きます。その場合、更新後に来る読み取りクエリは、ここで説明されているように更新が完了するのを待ちますかhttp://dev.mysql.com/doc/refman/5.0/en//table-locking.htmlまたは共有ロックを取得します更新クエリが起動される前にあった読み取りクエリと一緒に?

4

2 に答える 2

1

データベースから読み取るときに共有ロックを取得する必要はありません。実際、デフォルトのトランザクション分離レベルでは、一貫性のあるスナップショットから読み取られた1つのトランザクション内の通常のクエリをREPEATABLEREADします。SELECTロックは取得および必要ありません。このトランザクション内では、他のトランザクションでコミットされた変更は表示されません。

共有ロックは取得されないため、クエリを更新するための排他ロックは、他のセッションにファイルされた順序ですぐに付与されます。

MySQLドキュメントは次のように述べています

一貫性のある読み取りは、InnoDBがREADCOMMITTEDおよびREPEATABLEREAD分離レベルでSELECTステートメントを処理するデフォルトのモードです。一貫性のある読み取りでは、アクセスするテーブルにロックが設定されないため、他のセッションは、テーブルで一貫性のある読み取りが実行されると同時に、これらのテーブルを自由に変更できます。

デフォルトのREPEATABLEREAD分離レベルで実行していると仮定します。一貫性のある読み取り(つまり、通常のSELECTステートメント)を発行すると、InnoDBは、クエリがデータベースを認識する時点をトランザクションに提供します。タイムポイントが割り当てられた後に別のトランザクションが行を削除してコミットした場合、その行は削除されたとは見なされません。挿入と更新は同様に扱われます。

于 2013-01-02T11:28:32.450 に答える
0

Mysql Insert Delayedを見てみることができますINSERT DELAYED

残念ながら、innodb では利用できません。

PS: テーブルに既に共有ロックがある場合、排他ロックを取得することはできません。したがって、基本的に、あなたの状況では、3回の読み取りで共有ロックが取得され、1回の挿入で排他ロックが必要になります。挿入は、選択が終了した後にのみロックを取得できます。

于 2012-12-31T11:45:43.600 に答える