ホームページ  >  記事  >  データベース  >  mysql アドバンスト (4) mysql 選択

mysql アドバンスト (4) mysql 選択

黄舟
黄舟オリジナル
2017-02-09 15:15:29947ブラウズ

select * for update in mysql

注:

FOR UPDATE は InnoDB にのみ適用され、有効にするにはトランザクション ブロック (BEGIN/COMMIT) 内にある必要があります。

関数

このステートメントで選択されたオブジェクトをロックします。これにより、選択後にこれらのオブジェクトを他の場所で変更することによって引き起こされるデータの不整合が防止されます。統計 (クエリ) の実行中に他のユーザーによってレコードが更新されないようにするために、ロックに For update 句を使用できます。このようにして、ロックが解除されるまで、他のユーザーはこれらのレコードを更新、削除、またはロックできなくなります。

dept から daptno を選択します。 deptno=25 更新の場合。

FOR UPDATE を使用してテーブルをロックする場合は、コミットを使用してロックされたレコードを解放する必要があります。


ロックは、ロック スコープ句とロック動作句の 2 つのカテゴリに分類されます。 ロック スコープ句: select...for update の後、of 句を使用して、選択の特定のデータ テーブルをロックすることを選択できます。デフォルトでは、of 句を使用しないことは、select 内のすべてのデータ テーブルをロックすることを意味します。 ロック動作句: for update 操作を実行するときの動作は、通常の select とは大きく異なります。一般に、選択ではデータがロックされているかどうかを考慮する必要はなく、複数バージョンの一貫した読み取り機能に基づいて、せいぜい前のバージョンを読み取ります。

ルール for UPDATE ステートメントは、クエリ結果内のタプルをロックします。これらのタプルは、このトランザクションがコミットされるまで、他のトランザクションの UPDATE、削除、および for UPDATE によって操作されません。



アプリケーションシナリオ

それでは、いつアップデートに使用する必要があるのでしょうか?ビジネスレベルのデータを排他的にする必要がある場合は、更新に使用することを検討できます。電車の切符の予約などでは、残りの切符が画面に表示されますが、実際に切符を発券する際には、他のクライアントによってデータが変更されていないことを再確認する必要があります。したがって、この確認プロセス中に、アップデートに使用できます。事前準備が必要な統一解法問題です。



InnoDB のデフォルトは行レベル ロックであるため、MySQL は主キーが「明示的に」指定されている場合にのみ行ロック (選択されたデータのみがロックされます) を実行します。それ以外の場合、MySQL はテーブル ロック (データ全体をロックします) を実行します。形状)。

例1

いくつかの例を示します:

select * from t for update 会等待行锁释放之后,返回查询结果。
select * from t for update nowait 不等待行锁释放,提示锁冲突,不返回结果
select * from t for update wait 5 等待5秒,若行锁仍未释放,则提示锁冲突,不返回结果
select * from t for update skip locked 查询返回查询结果,但忽略有行锁的记录

SELECT...FOR UPDATE ステートメントの構文は次のとおりです:


 SELECT ... FOR UPDATE [OF column_list][WAIT n|NOWAIT][SKIP LOCKED];

その中に:

OF句は列を指定するために使用されますつまり、行固有の列をロックします。

WAIT句は、無期限の待機を防ぐために、他のユーザーがロックを解放するのを待つ秒数を指定します。

「USE FOR UPDATE WAIT」句の利点は次のとおりです:
1 ロックされた行を無制限に待機することを防止します。
2 アプリケーションがロックの待機時間をより詳細に制御できるようにします。
3 これらのユーザーは無限に待つことができないため、対話型アプリケーションに非常に役立ちます
4 スキップロックが使用されている場合、ロックされた行をスキップでき、wait n によって引き起こされる「リソースビジー」例外レポートは報告されません


例 2

id と name の 2 つのフィールドがあり、id が主キーであるフォーム製品があるとします。

例1: (主キーを明示的に指定、このデータがあれば行ロック)

SELECT * FROM products WHERE id='3' FOR UPDATE;
SELECT * FROM products WHERE id='3' and type=1 FOR UPDATE;

例2: (主キーを明示的に指定、そのようなデータがなければロックなし)

SELECT * FROM products WHERE id='-1' FOR UPDATE;


例 2: (主キーなし、テーブル ロック)

SELECT * FROM products WHERE name='Mouse' FOR UPDATE;


例 3: (不明瞭な主キー、テーブル ロック)

SELECT * FROM products WHERE id<>&#39;3&#39; FOR UPDATE;


例 4: (不明瞭な主キー、テーブル ロック)

SELECT * FROM products WHERE id LIKE &#39;3&#39; FOR UPDATE;


注 1: FOR UPDATE は InnoDB にのみ適用され、有効にするにはトランザクション ブロック (BEGIN/COMMIT) 内にある必要があります。

注 2: ロック状況をテストするには、MySQL のコマンド モードを使用して 2 つのウィンドウを開いてテストできます。

これは、MySql 5.0 でテストした場合に実際に当てはまります。

さらに: MyAsim はテーブル レベルのロックのみをサポートしますが、InnerDB は行レベルのロックをサポートします。

(行レベルのロック/テーブルレベルのロック) ロックで追加されたデータは、他のトランザクションによってロックすることはできません。また、テーブルレベルのロックの場合、テーブルを変更 (変更、削除) することもできません。レコードがクエリされるかどうかに関係なく、ロックされます。

さらに、AとBの両方がテーブルIDをクエリしてもレコードをクエリできない場合、AとBはクエリに対して行ロックを実行しませんが、AとBの両方が排他ロックを取得します。このとき、Aは別のロックを挿入します。 B がすでにロックを持っている場合は、B が同じデータを挿入すると、ロックを取得しようとしたときにデッドロックが発生し、その時点で A がロックを解放します。ロックを取得して挿入が成功します。

知識の補足

ロックはデータベースにおいて非常に重要な概念であり、主にマルチユーザー環境でデータベースの整合性と一貫性を確保するために使用されます。 複数のユーザーが同じデータベース内のデータを同時に操作できる場合、データの不整合が発生することがわかっています。つまり、ロックがなく、複数のユーザーが同時にデータベースにアクセスする場合、トランザクションで同時に同じデータが使用されると問題が発生する可能性があります。これらの問題には、更新の喪失、ダーティ リード、反復不可能な読み取り、ファントム リードが含まれます:


1.更新損失の問題は、2 つ以上のトランザクションが同じ行を選択し、最初に選択された値に基づいてその行を更新した場合に発生します。各トランザクションは他のトランザクションの存在を認識しません。最後の更新は他のトランザクションによって行われた更新を上書きするため、データ損失が発生します。たとえば、2 人の編集者が同じ文書の電子コピーを作成するとします。各編集者は自分のコピーを個別に変更し、変更されたコピーを保存して元の文書を上書きします。変更のコピーを保存した最後の編集者は、最初の編集者が行った変更を上書きします。最初のエディタが終了するまで 2 番目のエディタが変更を加えられない場合、この問題は回避できます。


2. ダーティ リードとは、トランザクションがデータにアクセスし、そのデータを変更したが、その変更がまだデータベースに送信されていないとき、その時点で別のトランザクションもデータにアクセスし、そのデータを使用することを意味します。このデータはまだコミットされていないため、別のトランザクションによって読み取られたデータはダーティ データであり、ダーティ データに基づく操作は正しくない可能性があります。たとえば、編集者が電子文書に変更を加えているとします。変更プロセス中に、別の編集者がドキュメントのコピーを作成し (コピーには、これまでに行われたすべての変更が含まれます)、それを対象のユーザーに配布します。その後、最初の編集者は、これまでに加えた変更が間違っていたと判断し、編集内容を削除し、文書を保存しました。ユーザーに配布されたドキュメントには、もはや存在しない編集内容が含まれており、存在しなかったものとみなされます。この問題は、最初の編集者が変更を完了するまで誰も変更された文書を読み取ることができない場合に回避できます。


3.反復不可能な読み取りとは、トランザクション内で同じデータを複数回読み取ることを指します。このトランザクションが終了する前に、別のトランザクションも同じデータにアクセスします。その後、最初のトランザクションの 2 回のデータ読み取りの間で、2 番目のトランザクションの変更により、最初のトランザクションで 2 回読み取られたデータが異なる可能性があります。このように、トランザクション内で 2 回読み取られるデータは異なるため、Non-Repeatable Read と呼ばれます。たとえば、編集者は同じ文書を 2 回読みますが、その合間に作成者が文書を書き直します。編集者が文書をもう一度読むと、文書は変更されています。生の読み取りは再現できません。この問題は、作成者がすべての執筆を終えた後にのみ編集者が文書を読み取ることができるようにすれば回避できます。


4.ファントム読み取りとは、トランザクションが独立して実行されない場合に発生する現象を指します。たとえば、最初のトランザクションがテーブル内のデータを変更し、この変更にはテーブル内のすべてのデータ行が含まれます。同時に、2 番目のトランザクションもこのテーブルのデータを変更します。この変更により、テーブルに新しいデータの行が挿入されます。その後、最初のトランザクションを操作するユーザーは、あたかも幻覚が起こったかのように、テーブル内にまだ変更されていないデータ行が存在することに気づくでしょう。たとえば、編集者が作成者によって送信されたドキュメントを変更しますが、プロダクションがその変更をドキュメントのマスター コピーにマージすると、作成者が新しい未編集の内容をドキュメントに追加したことがわかります。この問題は、編集者と制作部門が元のドキュメントの作業を完了するまで、誰もドキュメントに新しい内容を追加できないようにすれば回避できます。


したがって、複数のユーザーによる同時アクセスを処理する方法はロックすることです。ロックは、他のトランザクションが指定されたリソース制御にアクセスするのを防ぎ、同時実行制御を実現するための主要な手段です。ユーザーがデータベース内のオブジェクトをロックすると、他のユーザーはそのオブジェクトにアクセスできなくなります。同時アクセスに対するロックの影響は、ロックの粒度に反映されます。ロックされたリソースを制御するには、まずシステムのスペース管理を理解する必要があります。

上記は MySQL Advanced (4) の mysql 選択の内容です。さらに関連する内容については、PHP 中国語 Web サイト (www.php.cn) に注目してください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。