[PHP-users 14928]Re: [PHP-users14665]PEARでクエリが実行されるときとされない時がある
Osamu Shigematsu
m5issige @ mr.hitachi-medical.co.jp
2003年 4月 25日 (金) 15:17:01 JST
重松です。こんにちは。
今回のケースでは、PostgreSQL を使うと明示してあるので、まず、
PostgreSQL に限定して、考えてみました。
その上で、
> rollback()メソッドを呼んで実際にロールバックが行われるのは、
> autocommitをデフォルトのtrueからfalseに変えた後に、更新系のsqlが
> 成功している場合のみのようです。
>
> sorako yamamotoさんの場合はtrueのままなのでロールバックは
> この場合、query('ROLLBACK')メソッドのコールですね。
で、これなんですけど、私は思いっきり誤解していたようなので、
整理してみました。
# きっと他の人にも参考になるはず。長いですがご容赦を。
rollback() は以下のように実装されています。
function rollback()
{
if ($this->transaction_opcount > 0) {
$result = @pg_exec($this->connection, "abort;");
$this->transaction_opcount = 0;
if (!$result) {
return $this->pgsqlRaiseError();
}
}
return DB_OK;
}
つまり、rollback 処理が実行されるかどうか、それは即ち、
transaction_opcount が 0 より大きな場合のようです。
そして、この transaction_opcount を ++ しているのは、
ただ一箇所、simpleQuery() 内部であり、
function simpleQuery($query)
{
$ismanip = DB::isManip($query);
$this->last_query = $query;
$query = $this->modifyQuery($query);
if (!$this->autocommit && $ismanip) {
if ($this->transaction_opcount == 0) {
$result = @pg_exec($this->connection, "begin;");
if (!$result) {
return $this->pgsqlRaiseError();
}
}
$this->transaction_opcount++;
}
// 省略
}
のようになっており、transaction_opcount が increment されるのは、
(1) ! autocommit、即ち autocommit が false の場合、かつ、
(2) 更新処理が行われる SQL 文である。即ち、DB::isManip() の戻り値が真。
-> 行えたかどうかではなく、構文の確認の結果である。
ということのようですね。
だとすると、明示的に autoCommit(false) した場合に、自動的に BEGIN,
COMMIT 等が実行され (もちろん、DB によって変わると思います)、
デフォルトでは、自前処理することがあるってことですね。
また、今回の PostgreSQL の場合は、modifyQuery() は空っぽでしたが、
MySQL の場合、この部分で query を実行しているようです。
なので、このあたりは、処理系によって、実行される内容が違う、
ということのようです。
逆説的に言えば、simpleQuery() は、どのような関数として定義されているか、
それをまず明確にした方がいいのかもしれません。
けど、
http://pear.php.net/manual/ja/core.db.php
には、そういうレベルの文章は、見当たりませんでした。
Mashiki さん、細かいなんてとんでもない。
誤りをフォローしてくださって、ありがとうございました。
まだ、誤解しているところなんかがありそうなので、
嘘がありましたら、指摘 (& 訂正) いただければと思います。
--
Osamu Shigematsu <m5issige @ mr.hitachi-medical.co.jp>
PHP-users メーリングリストの案内