sql >> データベース >  >> RDS >> Mysql

SELECT ... FORUPDATEを使用する場合

    部屋とタグの間の一貫性を実現し、部屋が削除された後に部屋が返されないようにする唯一のポータブルな方法は、SELECT FOR UPDATEで部屋をロックすることです。 。

    ただし、一部のシステムでは、ロックは同時実行制御の副作用であり、FOR UPDATEを指定しなくても同じ結果が得られます。 明示的に。

    この問題を解決するには、スレッド1でSELECT id FROM rooms FOR UPDATEを実行する必要があります。 、これにより、スレッド2がroomsから削除されるのを防ぎます。 スレッド1が完了するまで。それは正しいですか?

    これは、データベースシステムが使用している同時実行制御によって異なります。

    • MyISAM MySQLで (および他のいくつかの古いシステム)は、クエリの間、テーブル全体をロックします。

    • SQL Server内 、SELECT クエリは、調査したレコード/ページ/テーブルに共有ロックを設定しますが、DML クエリは更新ロックを配置します(後で排他的ロックに昇格されるか、共有ロックに降格されます)。排他的ロックは共有ロックと互換性がないため、SELECT またはDELETE 別のセッションがコミットするまでクエリはロックされます。

    • MVCCを使用するデータベース (Oracleのように 、PostgreSQLMySQL InnoDBを使用 )、DML クエリは(何らかの方法で)レコードのコピーを作成し、通常、リーダーはライターをブロックしません。その逆も同様です。これらのデータベースの場合、SELECT FOR UPDATE 便利です:SELECTのいずれかをロックします またはDELETE SQL Serverと同様に、別のセッションがコミットされるまでクエリを実行します

    いつREPEATABLE_READを使用する必要がありますか トランザクション分離とREAD_COMMITTED SELECT ... FOR UPDATEを使用 ?

    通常、REPEATABLE READ ファントム行(変更されるのではなく、別のトランザクションで表示または非表示になった行)を禁止しません

    • Oracle内 以前のPostgreSQL バージョン、REPEATABLE READ 実際にはSERIALIZABLEの同義語です 。基本的に、これは、トランザクションが開始後に行われた変更をトランザクションが認識しないことを意味します。したがって、このセットアップでは、最後のThread 1 クエリは、部屋が削除されたことがないかのように部屋を返します(これはあなたが望むものである場合とそうでない場合があります)。削除された後に部屋を表示したくない場合は、SELECT FOR UPDATEで行をロックする必要があります

    • InnoDB内 、REPEATABLE READ およびSERIALIZABLE 異なるものです:SERIALIZABLEのリーダー モードは、評価するレコードの次のキーのロックを設定し、同時のDMLを効果的に防止します それらの上に。したがって、SELECT FOR UPDATEは必要ありません。 シリアル化可能モードですが、REPEATABLE READで必要です。 またはREAD COMMITED

    分離モードの標準では、クエリに特定の癖が見られないことを規定していますが、その方法(ロックまたはMVCCを使用)は定義されていないことに注意してください。 またはそれ以外の場合)。

    SELECT FOR UPDATEは必要ありません 「「特定のデータベースエンジン実装の副作用のために」追加する必要がありました。



    1. 巨大なテーブルの列タイプを変更する

    2. SQLServerの特定のテーブルを参照するすべての外部キーを返す

    3. SQL Serverネットワークインターフェイス:接続文字列が無効です[87]

    4. Javaを使用してSSH経由でリモートMySQLデータベースに接続します