同時アクセスについて

このQ&Aのポイント
  • mysqlでトランザクションを使いたいです
  • MyISAMを使ってきましたが、InnoDBに変更するだけで同時アクセスが可能になるのでしょうか?
  • pdoでUPDATE文を実行する際には何か特別な処理が必要でしょうか?
回答を見る
  • ベストアンサー

同時アクセスについて

プログラム初心者です mysqlでトランザクションを使いたいです いままでMyISAMを使ってきました。これをInnoDBにするだけで同時アクセスが可能になるのでしょうか? sqlのupdateもトランザクションは効くのでしょうか? pdoのほうでなにかやることはありますか?こんな感じのupdateを実行したいです $pdo->prepare('UPDATE point_table SET point = point+1 WHERE id = ?'); $stmt->bindValue(1, 15, PDO::PARAM_INT); $stmt->execute(); よろしくお願いします

  • flash0
  • お礼率97% (297/306)
  • PHP
  • 回答数3
  • ありがとう数13

質問者が選んだベストアンサー

  • ベストアンサー
noname#244856
noname#244856
回答No.3

画像小さくなっちゃったのでこっちで↓ http://qiita.com/mpyw/items/b00b72c5c95aac573b71#4-13

flash0
質問者

お礼

見やすかったです 簡単な加算だとなしでもいいのですね。勉強になりました。ありがとうございます

その他の回答 (2)

noname#244856
noname#244856
回答No.2

素晴らしい記事を見つけました。 MySQLのトランザクション分離レベル http://tree-tips.appspot.com/mysql/transaction_isoration/ ロストアップデートの有無を見るためのスクリプトを2つ用意します。point_tableにあらかじめレコードを1つだけ入れておいてください。Aを実行後10秒以内にBを実行し、2つのスクリプトがどちらも実行完了したあとの結果がどうなるかを、「//」のコメントアウトがある場合と無い場合で比較してみてください。 [スクリプトA] // $pdo->exec('SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE'); $pdo->beginTransaction(); $point = $pdo->query('SELECT point FROM point_table')->fetchColumn(); sleep(10); $pdo->exec('UPDATE point_table SET point = ' . ++$point); $pdo->commit(); [スクリプトB] // $pdo->exec('SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE'); $pdo->beginTransaction(); $pdo->exec('UPDATE point_table SET point = point + 100'); $pdo->commit(); RepeatableReadの方では「+1」、Serializableの方では「+101」される結果になると思います。ただしこのようにSerializableレベルでトランザクション分離が必要になるケースは非常に稀です。「同時アクセス」という言葉でくるめてしまわずに、自分が必要としている最低限度のレベルを探してみてください。むしろ単純に加減算する程度ならばトランザクション処理の必要性すら無くなったりします。

flash0
質問者

お礼

回答ありがとうございます トランザクションもいろいろレベルがあるのですね 自分が考えていたよりも奥が深かったのです(汗

noname#244856
noname#244856
回答No.1

毎度毎度になりますがまとめ貼りますね(笑) Qiita - PHPでデータベースに接続するときのまとめ #トランザクション処理 http://qiita.com/mpyw/items/b00b72c5c95aac573b71#2-22 InnoDBは4レベルのトランザクション分離をサポートしており、一番安全なようにアクセスごとに完全分離させたいならば $pdo->exec('SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE') を実行してください。

flash0
質問者

お礼

回答ありがとうございます なんとか出来た?と思うのですが、見た目が変わらないのでなんともいえません トランザクションが成功しているか確認する方法はありますか?

関連するQ&A

  • PDOのprepareでLIKEの部分一致が使えません・・

    http://d.hatena.ne.jp/Sybian/20070521/p1 のサイトの例のように、LIKE '%文字列%' をprepareしようとしたのですが上手く結果が返りません。 PDOのプリペアステートメントは、 LIKEの部分一致や先頭一致に非対応なのでしょうか? $query="SELECT * FROM table WHERE id=:id OR like name='%:name%'"; $pdo=new PDO('mysql:host=localhost;dbname=database','user','password'); $stmt=$pdo->prepare($query); $stmt->bindValue(':id',$id,PDO::PARAM_INT); $stmt->bindValue(':name',$name,PDO::PARAM_STR); $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_ASSOC);

    • ベストアンサー
    • PHP
  • PDO で IN句を利用することができません

    PDOでIN句を使用しているのですが、正しく動作しません。 $stmt = $pdo->prepare('SELECT * FROM hoge where id in (?)'); $stmt->bindValue(1, '123, 456, 789'); $stmt->execute(); var_dump($stmt->fetchAll()); fetchAllを行っても複数のレコードがかえってこず、ヒットした最初の1行のレコードしか取得することができません。PDOでIN句を使用することはできないのでしょうか? DBMSはMySQLを使用して、PHPは5.2.6を使用しています。 ちなみに $stmt = $pdo->prepare('SELECT * FROM hoge where id in (?, ?, ?)'); $stmt->bindValue(1, 123); $stmt->bindValue(2, 456); $stmt->bindValue(3, 789); $stmt->execute(); では、fetchAll で複数のレコードが返ってきます。 どうしてもpreparedで単一のIN句を使いたいのですが、何か良い方法はありますでしょうか?

    • 締切済み
    • PHP
  • PHPからSQL文で〇〇か〇〇か〇〇という時に

    PHPからMYSQLに問い合わせでご質問です。 実行している文です(SELECT文から) SELECT * FROM users WHERE id = ? AND level = ?' ))); $stmt->bindValue(1, $id, PDO::PARAM_INT); $stmt->bindValue(2, $level, PDO::PARAM_INT); $stmt->execute(); return $stmt->fetchAll(); } このような感じでユーザーIDとユーザーのレベルを判別しているものですが、IDはセッションを入れレベルに2と3と4の人を抽出という場合がわからずご質問させて頂きました。 ORを使って WHERE id = ? AND level = ? OR id = ? AND level = ? OR id = ? AND level = ? OR id = ? AND level = ? $stmt->bindValue(1, $id, PDO::PARAM_INT); $stmt->bindValue(2, $level, PDO::PARAM_INT); $stmt->bindValue(3, $id, PDO::PARAM_INT); $stmt->bindValue(4, $level, PDO::PARAM_INT); $stmt->bindValue(5, $id, PDO::PARAM_INT); $stmt->bindValue(6, $level, PDO::PARAM_INT); のような感じで当てはめたいものを書くのかと思ったり、もっときれいな書き方というか正しい書き方がありそうな気がしてご質問させて頂いた限りです。 どうぞよろしくお願いいたします。

    • ベストアンサー
    • PHP
  • ステートメントが必要です。???

    いつも大変お世話になり誠にありがとうございます。 標記の件。 下記のコードの一番下の}にステートメントが必要です と出ます。 どういう意味でしょうか? どうか教えてください。 宜しくお願い申し上げます。      記 function blogUpdate($blogs) { $sql = "UPDATE $this->table_name SET title = :title, content = :content, category = :category, publish_status = :publish_status Where id = :id"; $dbh = $this->dbConnect(); $dbh->biginTransaction(); try { $stmt = $dbh->prepare($sql); $stmt->bindValue(':title', $blogs['title'], PDO::PARAM_STR); $stmt->bindValue(':content', $blogs['content'], PDO::PARAM_STR); $stmt->bindValue(':category', $blogs['category'], PDO::PARAM_INT); $stmt->bindValue(':publish_status', $blogs['publish_status'], PDO::PARAM_INT); $stmt->bindValue(':id', $blogs['id'], PDO::PARAM_INT); $stmt->execute(); $stmt->commit(); echo 'ブログを更新しました!'; } catch (PDOException $e) { $dbh->rollBack(); exit($e); } }

    • ベストアンサー
    • PHP
  • PDOの使い方について

    PDOの使い方について教えてください。 例えば $st = $pdo->prepare("SELECT * FROM user_table WHERE id=:id"); $st->bindValue(':id',$id, PDO::PARAM_INT); $st->execute(); を $st = $pdo->prepare("SELECT * FROM user_table WHERE id='$id' "); $st->execute(); のように記載してはいけないのでしょうか? セキュリティ上問題があるのでしょうか? よろしくお願い致します。

    • 締切済み
    • PHP
  • SQLインジェクション対策

    SQLインジェクション対策として、変数を直接SQLに埋め込むのではなく、PDOのprepareメソッドを利用して作成したステートメントに値をバインドする形式にする場合、ユーザー定義関数をどのように 修正すればいいですか? function update_item_stock($db, $item_id, $stock){ $sql = " UPDATE items SET stock = {$stock} WHERE item_id = {$item_id} LIMIT 1"; return execute_query($db, $sql); } function execute_query($db, $sql, $params = array()){ try{ $stmt = $db->prepare($sql); return $stmt->execute($params); }catch(PDOException $e){ set_error('更新に失敗しました。'); } return false; } 上記のユーザー定義関数を下記のようにbindValueを用いて表す場合、$stmt->bindValueの部分を 上記のどこに追加すればいいですか? try { $sql = 'UPDATE item_stock SET stock = ?, update_date = ? WHERE item_id = ?'; $stmt = $db->prepare($sql); $stmt->bindValue(1, $update_stock, PDO::PARAM_INT); $stmt->bindValue(2, $date, PDO::PARAM_STR); $stmt->bindValue(3, $item_id, PDO::PARAM_INT); $stmt->execute(); $complete_msg[] = '在庫変更に成功しました。'; } catch (PDOException $e) { $err_msg[] = '更新に失敗しました。理由:' . $e->getMessage(); }

    • 締切済み
    • PHP
  • PDOで取得すると全てSTRING型で取得する?

    PDOを利用してprepareとbindValueでPDO::PARAM_INTなどと型指定をしてINSERTしているのですが、ネットをいろいろ見てみると「型指定をしてもexecute()時に全ての型は文字列として扱われる」と書いています。 これはデータベースの各カラムの型は無視して全て文字列としてINSERTしているのでしょうか? それともデータベースの型にMySQL側で勝手に変換して値を挿入してくれるのでしょうか? INSERTした数値を含むデータをprepareでSELECTしてexecute()してみると数値を含めて全てのカラムがstringとして取得しています。 MySQL側ではカラムの型をINTやFROATとして定義しても数値を文字列として挿入するとMySQL側も文字列として扱うのですか?それとも数値に変換されて挿入されますか? もし文字列として挿入されたらインデックスに影響しますか? いまいちどうすればいいのかわかりません。 一応 $id = 1; $name = "hoge"; $float = 0.055; $stmt = $dbh->prepare("INSERT INTO REGISTRY (id, name, float) VALUES (:id, :name, :float)"); $stmt->bindValue(:id, $id, PDO::PARAM_INT); $stmt->bindValue(:name, $name, PDO::PARAM_STR); $stmt->bindValue(:float, (string)$float, PDO::PARAM_STR); としています。 あと、PDO::PARAM_FLOATはないみたいで、PDO::PARAM_STRにすべきと書いていますが、このように指定してもMySQL側で勝手にFLOAT型に変換して値をINSERTするのでしょうか? どうぞよろしくお願い致します。

    • ベストアンサー
    • MySQL
  • バインドせずにPDOを使用すると

    PDOの使い方について教えてください。 例えば $id=3; $st = $pdo->prepare("SELECT * FROM user_table WHERE id=:id"); $st->bindValue(':id',$id, PDO::PARAM_INT); $st->execute(); を $id=3; $st = $pdo->prepare("SELECT * FROM user_table WHERE id='$id' "); $st->execute(); のようにバインドせずにPDOを使用するとSQLインジェクションなどのセキュリティ上問題があるのでしょうか? よろしくお願い致します。

    • 締切済み
    • PHP
  • PDO学び始めました

    プログラム初心者です PDO学び始めたのですがわからないとこがあります 質問1 名前付きプレースホルダの:nameの前についているコロンはなんですか? 変数なんでしょうか? 質問2 bindValueとbindParamがあるようですが普通につかう範囲では数値も文字もbindValueを使うだけでいいですか? 質問3 ユーザー入力のない値の場合はbindValueを使わずにprepareとexecuteのみでいいですか? 質問4 下記のように$nameの変数が後から登場しているのにエラーにならないのはなんでなんですか? $stmt = $pdo -> prepare("INSERT INTO テーブル名 (name, value) VALUES (:name, :value)"); $stmt->bindParam(':name', $name, PDO::PARAM_STR); $stmt->bindValue(':value', $value, PDO::PARAM_INT); $name = 'one'; $value = 1; $stmt->execute(); よろしくお願いします

    • ベストアンサー
    • PHP
  • PDOがうまく動かない

    PDOがうまく動かなくて困っています。 $get_id = $_GET['id']; $stmt = $pdo->query("SELECT * FROM table where hoge = ':id'"); $stmt->bindValue(":id",$get_id, PDO::PARAM_STR); $stmt->execute(); if($row = $stmt->fetch()) { echo "あああ"; } $get_id = $_GET['id']; $stmt = $pdo->query("SELECT * FROM table where hoge = '$get_id'"); if($row = $stmt->fetch()) { echo "あああ"; } 2つ目は「あああ」と表示されるのですが、1つ目は何も表示されません。 よろしくおねがいします。

    • ベストアンサー
    • PHP

専門家に質問してみよう