(14) SQLiteでトランザクション

投稿者: | 2016年11月9日

この記事は最終更新から 778日 が経過しています。

やってみたいこと

■OKパターン
begin → 複数Query成功 → commit (DBが変更される)
■NOKパターン
begin → 複数Queryの一部失敗 → rollback (DBまったく変更されず)
のアレです。
 
実行サンプルはこちらです。
(1) OKパターン
http://www.dogrow.net/php/sample/00014/?name=Frank&ferr=0
(2) NOKパターン
http://www.dogrow.net/php/sample/00014/?name=Jenny&ferr=1

プログラム作成

プログラムの仕様は以下の通り。
・引数で名前(name)と強制エラー発生有無(ferr)を渡す。
・ferr=0のとき、name(1)とname(2)をDBに登録する。
・ferr=1のとき、name(1)とname(2)をDBに登録しようとするが、name(2)登録時に失敗し、DBにはname(1)も登録されていない。

<!DOCTYPE html>
<HTML>
<HEAD>
<META CHARSET="UTF-8" />
<TITLE>SQLiteサンプル</TITLE>
</HEAD>
</BODY>

<?php
  $db_file_path = "mydb.db";    // SQLite DBファイル名

  // 引数から新規登録名を取得
  $name = $_GET['name'];
  // 強制エラー発生指定有無を取得
  $ferr = $_GET['ferr'];

  // DBファイル存在確認
  $isDbExist = file_exists($db_file_path);

  // DBオープン
  $db = new SQLite3($db_file_path);
  // 例外を許可
  $db->enableExceptions(TRUE);

  // DBは新規作成?
  if($isDbExist === FALSE){
    // テーブル作成 (ID, 名前, 登録日時)
    $db->exec("CREATE TABLE mytbl (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, register TEXT);");
  }

  // DB更新日時文字列を作成
  $dateTime = strftime("%G-%m-%d %H:%M:%S", time());

  $db->exec('begin');
  try {
    if($ferr == 0){
      // 引数で指定された名前を登録
      $db->exec("INSERT INTO `mytbl` (name,register) VALUES('".$name."(1)', '$dateTime');");
      $db->exec("INSERT INTO `mytbl` (name,register) VALUES('".$name."(2)', '$dateTime');");
    }
    else{
      // 強制的にエラーを発生させる
      $db->exec("INSERT INTO `mytbl` (name,register) VALUES('".$name."(1)', '$dateTime');");
      $db->exec("INSERT INTO `mytbl` (name,register) VALUES('".$name."(2)', '$dateTime','dummy');");
    }
    $db->exec('commit');
  }catch(Exception $e){
    echo "[".__LINE__."] Caught exception: ".$e->getMessage();
    $db->exec('rollback');
  }

  >// 既存の登録データを一覧表示
  $result = $db->query("SELECT * FROM `mytbl`;");
  $nCnt = 0;
  while ($row = $result->fetchArray()) {
    echo "<hr />";
    print_r($row);
    >//var_dump($row);
    $nCnt++;
  }
  // DBクローズ
  $db->close();

  if($nCnt > 10){
    // データベース削除
    unlink("mydb.db");
  }
?>

</BODY>
</HTML>

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)