php
  • mysql
  • locking
  • 2012-02-08 27 views 3 likes 
    3

    私はmysqlテーブルfg_stockを持っています。この表では、ほとんどの場合、同時アクセスが行われています。このコードを使用しましたが、動作しません。PHPを使ったMYSQLテーブルのロック

    <?php 
        mysql_query("LOCK TABLES fg_stock READ"); 
    
        $select=mysql_query("SELECT stock FROM fg_stock WHERE Item='$item'"); 
    
        while($res=mysql_fetch_array($select)) 
        { 
         $stock=$res['stock']; 
         $close_stock=$stock+$qty_in; 
         $update=mysql_query("UPDATE fg_stock SET stock='$close_stock' WHERE Item='$item' LIMIT 1"); 
        } 
    
        mysql_query("UNLOCK TABLES");  
    ?> 
    

    これは問題ありませんか?

    +0

    '$ qty_in 'はどこから来たのですか?あなたのSQLは私にとって意味をなさない、これははるかに簡単に行うことができるようだ。 – CodeZombie

    +0

    SELECTが複数のレコードを返す場合(ループを使用している場合)、UPDATEはLIMITを置いても同じ繰り返しレコードでは機能しない可能性があります。あなたのSELECTがレコードを1つしか返さない場合は、ループは必要ありませんが、ループはあなたのデータを傷つけることはありません。 – thevikas

    答えて

    1

    http://dev.mysql.com/doc/refman/5.0/en/internal-locking.html

    mysql> LOCK TABLES real_table WRITE, temp_table WRITE; 
    mysql> INSERT INTO real_table SELECT * FROM temp_table; 
    mysql> DELETE FROM temp_table; 
    mysql> UNLOCK TABLES; 
    

    だからあなたの構文が正しいです。別の質問からまた

    トラブルシューティング:あなたがロックされていない別のテーブルで を動作するようにしようとしてテーブルロックの成功のためにテストすることができます。ロックを取得した場合は、 ロックステートメント に含まれていないテーブルに書き込もうとするとエラーが発生します。

    代替ソリューションを検討してください。ロックする代わりに、 where句の一部として変更された要素を含む更新を実行します。 を読んでから変更しているデータが変更された場合、更新は「失敗」し、ゼロ行が変更されたことを返します。この は、テーブルロックと、デッドロックを含む となる恐ろしい恐怖を排除します。 PHP, mysqli, and table locks?

    4

    それはあなたが(テーブルから特定の行にアクセスしようとしている明らかだとき

    を「同時アクセスは、この表に起きている時間のほとんどは、」なぜ、あなたは、テーブル全体をロックしたいですWHERE Item = '$ item')?問題のテーブルのMyISAMストレージエンジンを実行している可能性があるので、代わりにInnoDBエンジンを使用する必要があります。テーブル全体をロックする必要がないように行レベルのロックをサポートしている点が強みです。

    4

    なぜあなたはテーブルをロックする必要がありますか?

    mysql_query("UPDATE fg_stock SET stock=stock+$qty_in WHERE Item='$item'"); 
    

    これだけです!テーブルをロックする必要がなく、クエリのセットで不必要なループが不要です。たとえば、$ qty_in(もちろん整数の場合)にintval php関数を使ってSQLインジェクションを避けてみてください。

    おそらくtime concurrent accessは、クエリの数が多すぎるため、最適化されていないデータベースが原因で発生します。

    ps:さらに、mysqlはループ内で常に同じレコードを更新できるので、あなたの例は意味をなさない。正確に更新したいレコードをMySQLに伝えていませんでした。 1つのレコードをItem = '$ item'で更新するようにのみ指示されました。次回の反復では、SAMEレコードは、すでに更新されたレコードとまだ更新されていないレコードの違いについてMySQLが認識しないため、再び更新される可能性があります。

    +0

    1か月分のプレミアムで償還できるコードがあるとします。誰かがそれを償還すると、それが存在するかどうかを確認し、存在する場合はデータベースから削除します。行をロックしないと、25回リフレッシュして25ヶ月になる人になります。 – apscience

    関連する問題