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

まだ存在しないInnoDB行をロックするにはどうすればよいですか?

    上記の答えは、SELECT ... FOR UPDATEが同時セッション/トランザクションが同じレコードを挿入するのを防ぐという点で真実ですが、それは完全な真実ではありません。私は現在同じ問題に取り組んでおり、次の理由により、SELECT ...FORUPDATEはその状況ではほとんど役に立たないという結論に達しました。

    同時トランザクション/セッションは、まったく同じレコード/インデックス値に対してSELECT ... FOR UPDATEを実行することもでき、MySQLは、エラーをスローすることなく、すぐに(非ブロッキングで)それを喜んで受け入れます。もちろん、他のセッションがそれを行うとすぐに、あなたのセッションもレコードを挿入できなくなります。また、あなたも他のセッション/トランザクションも状況に関する情報を取得せず、実際に挿入しようとするまで、レコードを安全に挿入できるとは考えていません。次に挿入しようとすると、状況に応じて、デッドロックまたは重複キーエラーが発生します。

    つまり、SELECT ... FOR UPDATEは、他のセッションがそれぞれのレコードを挿入するのを防ぎますが、SELECT ... FOR UPDATEを実行してそれぞれのレコードが見つからない場合でも、実際にはできない可能性があります。そのレコードを挿入します。 IMHO、「最初のクエリ、次に挿入」メソッドを役に立たなくします。

    この問題の原因は、MySQLが本当にする方法を提供していないことです。 存在しないレコードをロックします。 2つの同時セッション/トランザクションは、存在しないレコードを同時に「FOR UPDATE」でロックする可能性があります。これは、実際には不可能であり、開発を大幅に困難にするものです。

    これを回避する唯一の方法は、セマフォテーブルを使用するか、挿入時にテーブル全体をロックすることです。テーブル全体のロックまたはセマフォテーブルの使用の詳細については、MySQLのドキュメントを参照してください。

    ちょうど私の2セント...



    1. SQL Server(T-SQL)でUnixタイムスタンプを返す方法

    2. IRI-Windocksテストデータベースリポジトリ

    3. レストラン配信データモデル

    4. RecyclerViewへのSQLiteデータ