level 7 トランザクションの実装

最初の設計に沿って、実際のデータベースのアップデートを行う部分を作成する。WWWベースでも良い。 ロックは必要だろうか? 必要でないなら、それは何故か? ヒント: 最初の仕様をすべて実装するところまでは期待してません。
今回はデータベースに追加をするプログラムと、在庫を更新するプログラムを作成した。

プログラム

データベースに追加するプログラムtuika.php

define('USER','SYSTEM');
define('PASS','toybox');
define('DB','');

$con=oci_connect(USER,PASS,DB);          //データベースと通信をする。

print "choice tablename 1.AV・デジカメ館 2.家電・健康館 3.パソコン館 
4.文具・オフィス館 5.CD・DVD館 =>";              //テーブルを選択
$table = chop(fgets(STDIN));
if($table == 1){
$tablename = item_deji;
}if($table == 2){
$tablename = item_kaden;
}if($table ==3 ){
$tablename = item_pc;
}if($table == 4){
$tablename = item_ofice;
}if($table == 5){
$tablename = item_cdvd;
}else{
exit;
}

print "ID =>";
$ID = chop(fgets(STDIN));                  //登録するIDを入力

print "name =>";                                  //商品名を入力
$name = chop(fgets(STDIN));

print "maker =>";                     //メーカーを入力
$maker = chop(fgets(STDIN));

print "price =>";                        //値段を入力
$price = chop(fgets(STDIN));

print "point =>";                     //ポイントを入力
$point = chop(fgets(STDIN));

print "fix =>";
$fix = chop(fgets(STDIN));

print"number=>";
$number = chop(fgets(STDIN));

$sql="lock table ".$tablename." in exclusive mode nowait";                  //ロックを実行
$stmt=oci_parse($con,$sql);

    $sql="insert into ".$tablename." values('$ID','$name','$maker','$price','$point',
	'$fix','$number')";     //テーブルにデータを追加
    $stmt=oci_parse($con,$sql);
    if(!oci_execute($stmt,OCI_DEFAULT)){
        oci_rollback($con);        //エラーがでたらロールバックを実行
    }else{
        oci_commit($con);         //成功したらコミットを発行
    }

oci_close($con);

追加したい商品をテーブル別に更新するようにした。

在庫数を更新するプログラムupdate.php
define('USER','SYSTEM');
define('PASS','toybox');
define('DB','');

$con=oci_connect(USER,PASS,DB);

print "ID =>";
$ID = chop(fgets(STDIN));          //更新したい商品のIDを入力する

$sql="lock table ".$tablename." in exclusive mode nowait";          //ロックを実行
$stmt=oci_parse($con,$sql);

    $sql="update stock set ITEM_STOCK = ITEM_STOCK -1  where ITEM_ID = ".$ID."";
	//アップデートを実行
    $stmt=oci_parse($con,$sql);
    if(!oci_execute($stmt,OCI_DEFAULT)){
        oci_rollback($con);
    }else{
        oci_commit($con);
    }

oci_close($con);

今回は商品が購入されると仮定して在庫を1つ減らすように更新をした。

ロックについて

データベースにおいて更新をする際ロックは必要である。なぜならば別のユーザが同時 に更新をしようとした場合、User1による書き込みがUser2によって上書きされてしまい 正しく更新されないという問題が発生してしまうからである。
しかしロックをかけるといっても完全ロックを行ってしまうと、その間はselectなども 実行されなくなってしまうため不便である。そのためできるだけ小さい範囲でロックを かける必要がある。なので今回のプログラムで使用したロックは読み込み以外のアクセ スにのみロックをかけるものを使用した。