$ this-> db-> insert_id()给出致命错误postgresql codeigniter

时间:2013-02-13 16:21:02

标签: codeigniter postgresql

我正在使用 Codeigniter 2.0.1和Postgresql 8.1 。我的代码在try-catch块中使用事务。

有时在一个简单的插页上我会收到“致命错误”

  

致命错误:调用非对象中的成员函数row()   < ... path ...> /system/database/drivers/postgre/postgre_driver.php on   第357行

我的数据库配置是:

$db['default']['hostname'] = "localhost";
$db['default']['username'] = "***";
$db['default']['password'] = "***";
$db['default']['database'] = "***";

$db['default']['dbdriver'] = 'postgre';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = FALSE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';

$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;

导致错误的我的模型代码是“ $ id = $ this-> db-> insert_id(); ”。 我这样说是因为导致错误的行在insert_id()方法中,并且它在模型中只使用一次。 下面给出了模型的代码快照。

try {

    // CODE TO FILL UP $data ARRAY

    $this->DBquery("BEGIN");
    $this->DBinsert('<TABLE NAME>', $data);
    $id = $this->db->insert_id();

    // SOME MORE CODE
}
catch(Exception $e) {
    $this->DBquery("ROLLBACK");
    //echo $e->getMessage();
    return 0;
}
$this->DBquery("COMMIT");
return $id;

$ this-&gt; DBquery和$ this-&gt; DBinsert是我在基础模型类上创建的自定义方法,它扩展了CI_Model类。这些方法运作良好。

下面是postgre_driver.php中的insert_id方法,第357行是“ $ row = $ query-&gt; row();

function insert_id()
{
    $v = $this->_version();
    $v = $v['server'];

    $table  = func_num_args() > 0 ? func_get_arg(0) : NULL;
    $column = func_num_args() > 1 ? func_get_arg(1) : NULL;

    if ($table == NULL && $v >= '8.1')
    {
        $sql='SELECT LASTVAL() as ins_id';
    }
    elseif ($table != NULL && $column != NULL && $v >= '8.0')
    {
        $sql = sprintf("SELECT pg_get_serial_sequence('%s','%s') as seq", $table, $column);
        $query = $this->query($sql);
        $row = $query->row();
        $sql = sprintf("SELECT CURRVAL('%s') as ins_id", $row->seq);
    }
    elseif ($table != NULL)
    {
        // seq_name passed in table parameter
        $sql = sprintf("SELECT CURRVAL('%s') as ins_id", $table);
    }
    else
    {
        return pg_last_oid($this->result_id);
    }
    $query = $this->query($sql);
    $row = $query->row(); // LINE 357
    return $row->ins_id;
}

它更加令人困惑,因为问题并不总是如此。它有时会发生,但有足够的频率来阻碍工作。该系统正在被大约8-10个用户使用,因此我认为并发应该不是问题。 此外,我正在使用pconnect,连接数量是无限的。

1 个答案:

答案 0 :(得分:1)

这听起来好像你的一些插入语句失败了。如果像这样的事务内部出现错误,它可能会使事务无效。如果您查看日志文件,您可能会发现“当前事务已中止,命令被忽略直到事务结束”之类的条目。 (正在发生的事情是insert_id函数中的$ query变量没有收到有效的查询结果值,所以此时调用函数失败)

处理此问题的最佳方法可能是修改自定义DBinsert函数以返回指示插入操作成功或失败的值。 (您应该只能返回您在内部运行的任何insert命令的值)

然后,你可以这样做:

$insert_ret_val = $this->DBinsert('<TABLE NAME>', $data);
if($insert_ret_val){
    //insert success!
    $id = $this->db->insert_id();
}else{
    //handle failed insert here, rollback, whatever
}