2011-09-14 5 views
1

いくつかのコードを開発している最中に、競合状態の同時性の問題を避けるためにInnoDBテーブルを 'ロックする'必要がありました。ロックセッションが完了すると、ロックされたテーブル(他のセッションでロックされている)を読み込む並列セッションが誤ったデータを取得するので、 'read lock'は十分ではありません。Mysql InnoDBテーブルがロックされていますが、別のセッションから「選択」できます。何がありますか?

これまでのところ、私は '書き込みロック'が必要なのです。コメントはこれを歓迎しますが、(私の謙虚な心に)私はテーブルの完全なターミナルロック以外の方法は見えません。

私のテストでは、2人のmysqlコマンドラインセッションをオープンしました。どちらも通常のユーザ(rootでも同様のものでもありません)です。あるセッションで私はした: ロックテーブルmytable書き込み; ok(uery OK、0 rows affected ...) 2番目のコマンドラインセッションで同じDBに接続し、同じテーブルで簡単なselect *を実行しました。私の驚いたことに、私は完全な応答を得た。 実際のWebアプリケーションからのテストでは、Webアプリケーション(永続的な接続属性を持つPHP + PDO)を使用するいくつかのユースケースでは、コマンドラインまたはWebのmysql接続がロックが解除されるまでブロックされましたが、 (希望の)効果を引き起こしたものを特定し、異なる環境(PHPとPDOの詳細とコマンドライン対2つのコマンドラインセッション)も含みます。

私の質問は:なぜですか?書き込みロックされたテーブルで単純な「選択」を実行すると、2番目のコマンドラインセッションはなぜブロックされませんでしたか?

これは、行ベースのInnoDBロックの性質と関係がありますか?もしそうなら、これはどのように正確に関連していますか? How do私はInnoDBテーブルにこのような単純なロックを実装しています。私は、 '信号機'として動作する以外の目的を持たない「セマフォー」MyIsamテーブルを作成できることを知っていますが、それはDBレベルの保護の効果を失い、すべての保護がアプリケーション内で(または間違って実行されるように)移動します。レベル。

TIA!

MySQLバージョンは5.1.54(Ubuntu 11.04)です。

+1

http://dev.mysql.com/doc/refman/5.0/en/innodb-lock-modes.html –

答えて

2

InnoDBには行レベルのロックがありますが、マルチバージョンの同時実行制御http://en.wikipedia.org/wiki/Multiversion_concurrency_controlもあります。したがって、読者はライターによってブロックされる必要はありません。彼らはレコードの現在のバージョンを見ることができます。 (技術的な実装では、更新時に行が変更され、以前のエディションは古いトランザクションのために元に戻すために書き込まれます)

書き込みロックブロックリーダーを作成するには、 FOR UPDATE(つまり、SELECT * FROM my_table WHERE cola = n FOR UPDATE)。

+0

クイック返信をありがとう。はい、私はブロックするために読者が必要ですが、それを行うための最善の解決策は、いくつかの偽の_selectを行うことです... update_と私はどのような種類の選択をしてすぐにこれは、テーブル全体をロックしますか? –

+0

SELECT FOR UPDATEは、ロックが必要な行を読み込もうとしている選択をブロックします。テーブルロックではなく、通常の選択をブロックしません。分離レベルをSERIALIZABLEに変更すると選択をブロックできますが、実際にはそうしたくないと思います。 –

+0

要約すると、私が学んだことによると、InnoDB DB全体を簡単にロックすることはできませんが、SELECTを使用してUPDATEを使用すると、私が望むものを達成することができます。また、分離レベルで行うべき読書があり、それは私に仕事をさせるためのツールを提供します。助けてくれてありがとう! –

関連する問題