2012-12-29 17 views
5

私は、WebサービスをPHPで作成しています。これは、テーブルからの選択に基づいて一連の計算を行い、その後、新しい結果でテーブルを更新します。PHPのMySqlテーブルロック

しかし、別の人のセッションがまだ更新中である間に、他の人が同じWebサービスに電話をかけているのを防ぐ必要があります。

テーブル全体をロックして再度ロックを解除するのは正しいことですか?もしそうなら、PHP pdoを使ってmysqlテーブルをロックしてロックを解除するには?

+0

直接の回答ではありませんが、これは問題ではないと私は考えています。データベースからの計算およびデータのフェッチは、数ミリ秒以内に行われます。同じ時間にやりとりするチャンスや2人の人がとても小さいので、ほとんどの人はこのようなロックをしなくても構いません。 – OptimusCrime

+0

私はそれを実現します。しかし、データの破損が私のアプリケーションに大きな影響を与える可能性があるため、私はリスクを冒すつもりはありません。 – user1574041

+0

[データベーストランザクション](http://dev.mysql.com/doc/en/sql-syntax-transactions.html)を使用して、操作のアトミック性を確保します。 – eggyal

答えて

0

私がコメント投稿:

ない直接の答えを、私はこれは何の問題もないと思います。 データベースからの計算とデータのフェッチは、数分の数秒以内に行われます( ミリ秒)。チャンスか二人が同時に対話する は、ほとんどの人がこのようなロックを作るのを気にしないsoooo小さいです。

しかし、これらの計算が重要な場合は、新しいフィールドを追加することで、この問題を回避し、単にoccupiedbusyまたはそのような何か、それを呼び出すことができます。

スクリプトを実行するときに、このフィールドがたとえば1に設定されているかどうかを確認し、設定されている場合はスクリプトを1〜3秒間スリープ状態にしてから再試行します。このフィールドが0に設定されている場合は、1に更新し、計算を行い、再び0に戻します。

これにより、2人のユーザーが同時に同じ値にアクセスできなくなります。

+0

このアプローチの問題点は、両方のクライアントがどちらかを更新する前にチェックフィールドの値を読み取った場合、両方のクライアントがチェックフィールドの値を読み取った場合、両方のクライアントが処理を続けることができると考えられることです。並列アプリケーションの安全性を確保するために、CPUはオペレーティングシステムにAPIを提供し、RDBMSはロックメカニズムを実装する際にそのAPIを呼び出します。 **失敗することになるので、あなた自身でこれを構築しないでください**。代わりに、データベーストランザクションによって提供されるアトミック性を使用します。 – eggyal

+0

これは私がこのルートに行くことを喜んで解決策を実装するのが最も安全なようです。言われたエジプトの事件を防ぐための解決策はありますか? – user1574041

+0

@eggyal:他の答えはここに掲載されています。まったく同じ時間に2人がこれにアクセスすることはできません。それが起こるには速すぎます。 – OptimusCrime

3

MySQLのようなデータベース管理システムは、これらのような並行性の違反を防ぐのに十分スマートです。

データベース分離レベル(コミットされていない読み取り、コミットされた読み取り、繰り返し可能な読み取り、シリアライズ可能)、および考えられる問題(ダーティー読み取り、非繰り返し読み取り...) - >Wikipediaを探します。

個人的には、私はあなたのケースではテーブルロックをお勧めしません。 あなたの計算とデータベース操作をトランザクションにラップし、DBMSを使って自分のものを管理してください。

+0

しかし、私は現時点でこのようにしています: 1)私のテーブルで選択してください 2)その選択に基づいてPHPで私の計算を行います 3)PHP計算に基づいてそのテーブルを更新してください。 これはトランザクションで可能ですか?私は比較的新しいデータベースです。 – user1574041

+1

@ user1574041:[ロック...](http://dev.mysql.com/doc/en/innodb-locking-reads.html)のように、 'SELECT ... FOR UPDATE'を使うことができます。しかし、計算ロジックをPHPとSQLに転送することができます。これにより、1つの「UPDATE」文で実行されます。 'UPDATE myTable SET myColumn =(1 + myColumn)* 2 WHERE ...'。 – eggyal

+0

ありがとう@eggyal、私の推薦もあります。計算をphpで行う必要があり、テーブル全体をロックしたくない場合は、 'flock'のようなファイルベースのロック機構を調べるとよいでしょう:http://php.net/manual/en/ function.flock.php –