rakutoネット
お問合せ 免責事項 Q&A 掲示板 サイト管理 リンク サイトマップ
HOME > 排他処理

排他処理


排他処理

PHPではWebアプリケーションを作ることが大半だと思います。
その中でデータ更新するシステムを作られる場合、考えなければ
ならないことは、不特定多数のユーザーが更新を行うことです。
有名なもではファイルロックなどでしょうか。また、DBの場合では
トランザクション機能で対応するものなどが挙げられると思います。

この排他処理はかなり重要な仕組みだと思います。しかし、予算
などの都合で、一番最初に削られてしまう機能でもあります。
その原因は排他処理の重要性をクライアントが勘違いしている点に
あると思います。

「規模が小さいから同時にアクセスする人もいないし……」
この同時の中身が一瞬の処理と捕らえている人がいます。
カウンタなどでは読み書き処理が重なる一秒以下の処理もあるでしょうが
以下に示す例は結構あり得るものです。

排他処理の重要性を考えてみました。
例ではオフィス用のグループウェアを想定してます。

排他処理を考える

藤井さん入力中 時間13時00分
藤井さん(仮名)がAプロジェクトの見積もりを修正しています。

「Aプロジェクト」見積もり入力フォームが表示されています。
藤井さん電話中 時間13時03分
作業中の藤井さんに電話が入りました。

まだ、「Aプロジェクト」見積もり入力フォームが表示されています。
田中さん入力中 時間13時05分
田中さん(仮名)がAプロジェクトの見積もりを修正しようと入力フォームを開きました。

「Aプロジェクト」見積もり入力フォームが表示されています。


時間13時07分
田中さんがAプロジェクトの見積もりの修正が完了しました。

「Aプロジェクト」見積もりの修正完了が表示されました。
藤井さん入力中A 時間13時09分
電話が終わった藤井さんが再びAプロジェクトの見積もりを修正し、完了しました。

「Aプロジェクト」見積もりの修正完了が表示されました。
排他処理を行っていない場合、田中さんが修正した見積もりに藤井さんが上書きしてしまいます。
田中さんは藤井さんの修正中に作業をしています。この時田中さんが確認した見積もりは藤井さんが
修正する前のものです。
修正内容が同じ場合や藤井さんの修正が正しければ問題有りませんが、そうとも限りません。

そこでアプリケーション側で以下のような警告を出すなど排他処理をサポートしなければなりません。
「Aプロジェクト」見積もりの修正完了が表示されました。
「Aプロジェクト」が田中さんにより更新されています。

排他処理の方法

排他処理の方法
排他処理の方法としてはセッションの利用やフラグを用いるなど
色々あると思います。
私がよく使う方法はテーブルにタイムスタンプを用意する方法です。
修正前のタイムスタンプを持ちまわし、実際に更新をかける際にテーブル
にあるタイムスタンプと持ちまわした値が異なる場合に処理を発生させる
方法です。

同時に複数の人が修正できない様にロックする方法もありますが修正途中で
ブラウザが落ちてしまう場合など中断することを考えなければならず
面倒くさいと言う点からも上書きの際、警告出す方法を使ってしまいます。
排他処理は使う人間の判断に任すのが一番楽です。
CREATE TABLE project_tbl (
    id          INTEGER NOT NULL,
    avail       INTEGER DEFAULT 1,
    name        VARCHAR(64) NOT NULL,
    account     INTEGER NOT NULL,
    modify      TIMESTAMP NOT NULL,
    number      INTEGER,
    PRIMARY KEY (id)
)
CID 項目名 型名 NOT NULL 初期値 キー
0 id INTEGER notnull PRIMARY
1 avail INTEGER 1
2 name VARCHAR(64) notnull
3 account INTEGER notnull
4 modify TIMESTAMP notnull
5 number INTEGER
<?php
    /* 最終更新時間の取得 */
    $query = "SELECT modify FROM project_tbl WHERE id=16";
    $modify = $objdb->getOne($query);
    if (DB::isError($modify)){
        return false;
    }
 
    /* 持ち回していた更新時間と比較 */
    if ($_POST['modify'] != $modify){
        echo "修正中に他の方により更新されています。";
        return false;
    }
 
    /* 更新処理 */
    $now = date('Y-m-d H:i:s',time());
    $query = 
        "UPDATE 
            project_tbl 
        SET 
            number='{$number}',
            account='{$account}',
            modify='{$now}' 
        WHERE 
            id=16";
    $result = $objdb->query($query);
    if (DB::isError($result)){
        return false;
    }
    echo "修正が完了しました。";
 
?>
藤井さん入力中A 時間13時09分
電話が終わった藤井さんが再びAプロジェクトの見積もりを修正し、完了しました。

「Aプロジェクト」が田中さんにより更新されています。
藤井さんが修正内容を判断して改めて更新を行います。

<<カレンダー
PHP Tips PEAR DB>>

PHPリング

@PHP.ring Home
<5 <1 Random List 1> 5>

rktSQLite

  • sourceforge.jp

広告


アマゾン検索

サーチ:
Amazon.co.jpアソシエイト

カテゴリ

  •  Templateエンジンのすすめ Templateエンジンのすすめ
  •  SQLiteをやってみよう SQLiteをやってみよう
  •  SQLite SQLコマンド一覧 SQLiteコマンド一覧
  •  SQLite 管理プログラムSQLite 管理
  •  はじめてのEclipse はじめてのEclipse
  •  PHP SQLiteのTIPS PHP SQLiteのTIPS
  •  サンプル サンプル/ダウンロード
  •  リンク リンク
  •  掲示板 掲示板

メニュー

  •  incoude pathを通す
  •  カレンダー
  •  排他処理
  •  PEAR DB
  •  画像アップロード
  •  プログレスバー
  •  PATH_INFOで拡張子を隠す
  •  トラックバック
  •  PEARのトラックバック
  •  iMagickでGIFアニメ
  •  メモリ上の画像をImageMagickする
  •  暗号化と復号化
  •  strtotime()でmonth処理

キーワード検索

キーワード



最近のTB

  •  2006/03/13さくらのブログに挑戦[rakutoネットブログ]
  •  2006/01/20レーザーチャートの作成方法[脳内研究所]

Summary

  •     ATOM(XML)
  •     RDF(XML)
  •     RSS0.92(XML)
  •     RSS2.0(XML)

Powered by

  •     PHP
  •     Smarty
  •     SQLite
  •     MySQL
Copyright (C) 2005 `rakuto.net' All Rights Reserved.