質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.59%

MySQLのトランザクション中の意図しない挙動について教えて頂きたいです

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 567

nakashi

score 12

MySQLのトランザクション中の挙動について理解できていない所があり、投稿致しました。
下記に、「実行環境」、「使用テーブル」、「実行結果」、「私が期待していた結果」、「PHPプログラム」を示します。

PHPプログラム実行後、「tanaka」さんが二つ登録されています(下記「実行結果」ご参照)
これは下記の「私が期待していた結果」に反していて不思議に感じています。また何故このような結果になるのか分からずに悩んでいます。

よろしければ、こういった結果になる理由や、「私が期待していた結果」にするための方法について教えて頂ければ嬉しいです。


実行環境
MySQLバージョン:5.5.38
PHPバージョン:5.5.29
レンタルサーバ:kagoya
 

使用テーブル(testテーブル)
※engine:InnoDB、isolation:REPEATABLE-READ、id:auto_increment

id name
1 sato
2 suzuki

実行結果(testテーブル)

id name
1 sato
3 tanaka
4 tanaka

私が期待していた結果(testテーブル)

id name
1 sato
3 tanaka

PHPプログラム

<?php
session_start();
require_once('config.php');
require_once('functions.php');

// DB接続
$dbh = connectDb();

// トランザクション開始
$dbh->beginTransaction();

echo 'begin transaction:' . '<br>';

try {

    $sql = "delete from test 
        where id = :id";
    $stmt = $dbh->prepare($sql);
    $ret = $stmt->execute(array(
        ":id" => 2
    ));

    $sql = "select * from test";
    $stmt = $dbh->query($sql);
    $test = $stmt->fetchAll(PDO::FETCH_ASSOC);
    echo 'after delete:';
    var_dump($test);


    $sql = "insert into test (name) values (:name)";
    $stmt = $dbh->prepare($sql);
    $ret = $stmt->execute(array(
        ":name" => 'tanaka'
    ));

    // commit
    $dbh->commit();

    unset($dbh);

} catch (PDOException $e) {
    $dbh->rollBack();
    die($e->getMessage());
}

?>

※不思議なことにローカル環境(Windows、MySQL5.6.24、PHP5.6.8)では「私が期待していた結果」になっています。ローカル環境とKagoyaサーバ環境で挙動が違っていて更に悩んでいます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Orlofsky

    2019/11/19 00:06

    >思いもよらぬ挙動
    それで掲示板を読んでいる人は誰も理解できません。
    質問に具体的な内容を追記しては?別の質問になるなら別の質問を建てては?

    キャンセル

  • nakashi

    2019/11/19 01:10

    >質問に具体的な内容を追記しては?別の質問になるなら別の質問を建てては?
    失礼しました。質問内容を整理して書き直しました。(この掲示板に不慣れなのですみません。)

    キャンセル

  • m.ts10806

    2019/11/19 07:48

    基本は質問に追記してください。
    既に試してるかもしれませんが一度テーブル作り直して(データdeleteではなくDROP TABLEからCREATE TABLE)試してみてください。

    キャンセル

回答 3

checkベストアンサー

0

delete文でid=2のsuzukiを削除して、
auto incrementなidでtanakaをinseto into文したのを、
2度繰り返しただけじゃないの?

削除したidはリサイクルされないので。

一回しか実行してないのだとしたら、
ブラウザ拡張とかウイルス対策ソフトが先にページを読みに行っていないだろうか。
webサーバーのアクセスログに残るuser-agentがブラウザのものかどうか、
丁寧に洗ってみてほしい。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/18 23:11

    ありがとうございます。delete後、insertは1度しか行っていないです。
    それで「tanaka」さんが2人になる理由が検討付かず、悩んでいます。

    キャンセル

  • 2019/11/18 23:17

    何らかの方法手段で、そのページを2度読んでるはず。

    キャンセル

0

単純にどこかで2度読み込んでいるだけだと思いますが対処方法としては
deleteしたあとにrowCountして、0だったら処理を中断すればいいでしょう
(ただし削除しなくてもinsertしたいならロジックが違いますが)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

皆さま、色々とアドバイスをありがとうございます。
その後なのですが、無事に「期待していた結果」が出るようになりました。

時間に追われ慌てておりましたので、下記のような対応を連続でしてしまい、申し訳ありませんが原因の切り分けは十分に出来ておりません。
しかしながら、皆さまがおっしゃる通り、アクセスが2回発生していた可能性が非常に高いと思います。
アドバイスを参考に、KagoyaサーバでApacheアクセスログを取得するように設定しましたので、暫くはログを注意深く見ていこうと思います。

急な相談にも関わらず、多くの方にご意見を頂きましてありがとうございました。
助かりました。御礼申し上げます。


行った対応

[クライアント側]

  • PC再起動
  • ウイルス対策ソフトのバージョンアップ
  • Chrome拡張機能の停止
  • Windows更新プログラム適用

[サーバ側]

  • 新DB作成(新DBで実験)
  • PHP再起動&php.ini微修正(memory_limit等)
  • Apacheアクセスログ取得設定

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る