ユースケースは次のとおりです。
利用できる、または利用できない固有のコードがたくさんあるテーブルがあります。トランザクションの一部として、テーブルから使用できるコードを選択し、後でトランザクションの後半でその行を更新したいと思います。これは同時に多くのセッションで同時に発生する可能性があるため、理想的にはランダムレコードを選択し、テーブルで行レベルのロックを使用して、から行を選択するクエリによって他のトランザクションがブロックされないようにします。テーブル。
ストレージエンジンにInnoDBを使用していますが、クエリは次のようになります。
select * from tbl_codes where available = 1 order by rand() limit 1 for update
ただし、テーブルから1行だけをロックするのではなく、テーブル全体をロックすることになります。このクエリがテーブル全体ではなく行だけをロックするようにする方法について、誰かが私にいくつかのポインタを教えてもらえますか?
アップデート
補遺:rand()を実行するのではなく、selectで明示的なキーを指定することで、行レベルのロックを実現できました。私のクエリが次のようになったら:
クエリ1:
select * from tbl_codes where available = 1 and id=5 limit 1 for update
クエリ2:
select * from tbl_codes where available = 1 and id=10 limit 1 for update
ただし、それは実際には問題の解決には役立ちません。
補遺2:私が行った最終的な解決策
rand()にMySQLでいくつかの問題があることを考えると、私が選択した戦略は次のとおりです。
利用可能な場合は50個のコードID=1を選択し、アプリケーション層で配列をシャッフルして、順序にランダム性のレベルを追加します。
利用可能な場合はtbl_codesからIDを選択=1制限50
ロック付きの配列を選択できるようになるまで、シャッフルされた配列からループでコードをポップし始めます
select * from tbl_codes where available = 1 and id =:id