[PHP-users 23327]DataObjectで テーブルをロックするには

norioh @ kun.ne.jp norioh @ kun.ne.jp
2004年 9月 17日 (金) 12:22:42 JST


谷口と申します。

PHP 4.3.4
DB                        1.6.5   stable
DB_DataObject             1.7.2   stable
MySQL 4.0.18
という環境です。
DataObject で テーブルをロックするにはどうすればよろしいでしょうか。

以下のようにやってみましたがロックできませんでした。

<?php
/**
 * Hoge テーブルDAOクラス
 */
class HogeDAO {
    var	$_db = null;

    function HogeDAO(){
	$this->_db = DB_DataObject::factory('hoge');
    }

    /**
     * 最大の thread_hoge_no
     * を取得する
     * テーブルをロックした状態で、取得し、更新後開放
     */
    function getMaxThreadHogeNoByThreadNo($thread_no){
	$this->_db->whereAdd();
	$this->_db->whereAdd("thread_no = '" . $thread_no . "'");
	$this->_db->orderBy('thread_hoge_no DESC');
	$this->_db->limit(0, 1);
	$cnt = $this->_db->count();
	if($cnt == 0){
	    return 0;
	}
	$result = $this->_db->find();
	if(!$result){
	    return null;
	}
	$hoge = array();
	$hoge['thread_hoge_no'] = 0;
	while($this->_db -> fetch()){
	    $hoge = $this->_db->toArray();
	}
	return $hoge['thread_hoge_no'];
    }

    function lock(){
	$sql = "LOCK TABLES {$this->_db->__table} WRITE";
	return $this->_db -> query($sql);
    }

    function unlock(){
	$sql = "UNLOCK TABLES";
	return $this->_db -> query($sql);
    }

    function getHoge(){
	return $this->_db;
    }

}
?>

このクラスを


$hDAO = new HogeDAO();
$hoge = $hDAO->getHoge();
$hoge->setFrom($values);

$hDAO->lock();
$trNo = $hDAO->getmaxthreadHogeNoByThreadNo($_SESSION['thread']['thread_no']);
sleep(30);
if($trNo >= 0){
    ++$trNo;
    $hoge->setThread_hoge_no($trNo);
    $result = $hoge->insert();
}else{
    $result = false;
}
$hDAO->unlock();


のように使用して、スリープ中にスリープ無しのスクリプトでアクセスすると
ロックされてるテーブルにアクセスする部分で待たされるかと思っておりまし
たが、そのまま処理されて、thread_hoge_no が同じレコードが追加されてし
まいました。

実現したいことは、現在登録されている thread_hoge_no の最大値に1を加算
して次のレコードを追加するという処理です。thread_hoge_no は thread_no
をキーとして検索した場合は、ユニークです。thread_no は、1、2、3とあり
ますので、テーブル全体としては、thread_hoge_no は同じ番号もあります。

テーブルは、

hoge_no	ID プライマリーキー
thread_no スレッド番号
thread_hoge_no スレッドに対する hoge の番号
data データ

のような感じです。

ログは以下のようにでておりました。


dataobjects_hoge: CONNECT: USING CACHED CONNECTION
dataobjects_hoge: QUERY: LOCK TABLES hoge WRITE
dataobjects_hoge: query: QUERY DONE IN 0.000169038772583 seconds
dataobjects_hoge: CONNECT: USING CACHED CONNECTION
dataobjects_hoge: CONNECT: USING CACHED CONNECTION
dataobjects_hoge: CONNECT: USING CACHED CONNECTION
dataobjects_hoge: CONNECT: USING CACHED CONNECTION
dataobjects_hoge: QUERY: SELECT count(hoge.hoge_no) as DATAOBJECT_NUM FROM hoge WHERE thread_no = '15'
dataobjects_hoge: query: QUERY DONE IN 0.0011579990387 seconds
dataobjects_hoge: __find:
dataobjects_hoge: CONNECT: USING CACHED CONNECTION
dataobjects_hoge: CONNECT: USING CACHED CONNECTION
dataobjects_hoge: CONNECT: USING CACHED CONNECTION
dataobjects_hoge: QUERY: SELECT * FROM hoge WHERE thread_no = '15' ORDER BY thread_hoge_no DESC LIMIT 0, 1
dataobjects_hoge: query: QUERY DONE IN 0.00100183486938 seconds
dataobjects_hoge: __find: CHECK autofetchd
dataobjects_hoge: __find: DONE
dataobjects_hoge: FETCH: 略
dataobjects_hoge: fetchrow LINE: hoge_no = 138
dataobjects_hoge: fetchrow LINE: data = \u8c37\u53e3
dataobjects_hoge: fetchrow LINE: thread_no = 15
dataobjects_hoge: fetchrow LINE: thread_hoge_no = 19
dataobjects_hoge: fetchrow: hoge DONE
dataobjects_hoge: FETCH: N;
dataobjects_hoge: FETCH: Last Data Fetch'ed after 0.0026330947876 seconds
dataobjects_hoge: CONNECT: USING CACHED CONNECTION
dataobjects_hoge: QUERY: INSERT INTO hoge (data , thread_no , thread_hoge_no ) VALUES ('\u8c37\u53e3' , 15 , 76 )
dataobjects_hoge: query: QUERY DONE IN 0.000447034835815 seconds
dataobjects_hoge: CONNECT: USING CACHED CONNECTION
dataobjects_hoge: QUERY: UNLOCK TABLES
dataobjects_hoge: query: QUERY DONE IN 0.000185012817383 seconds




どうぞよろしくお願い致します。

-----
Norioh <norioh @ kun.ne.jp>


PHP-users メーリングリストの案内