PHP中使用PDO进行插入事务处理,lastInsertId 在第二条没有执行正确的情况下会返回上次执行成功的ID

PHP中使用PDO进行插入事务处理,lastInsertId 在第二条没有执行正确的情况下会返回上次执行成功的ID

首先我想重现一下这个错误:

测试表单如图,

主表:(先插主表)

附表:(再插附表)

这是我随便建的表,没什么真正的关系,主要是需要先对主表进行数据插入,再主表正确的基础上对附表进行插入。

$db = new DBUtil();

                $select = 'select user_id from users where user_email="'.$data['user_email'].'" or user_name="'.$data['user_name'].'"';
                $user_id = $db->sqlForArray($select);

                if($user_id) {
                    echo '用户或者邮箱已经被占用';
                } else {
                    //开启事务
                    $db->db->beginTransaction();

                    // 插入主表
                    $db->insertParams(
                        'insert into users(user_name,user_password,user_email,user_regdate) values(:user_name,:user_password,:user_email,now());',
                        $data
                    );
                    $last_userid = $db->getLastInsertId;
                    if(!$last_userid) {
                        $db->db->rollBack();exit();
                    }

                    $db->insertParams('insert into userinfo(user_id,user_qq,user_email,user_weibo,user_description) values('.intval($last_userid).',:user_qq,:user_email,:user_weibo,:user_description);',
                        $meta
                    );
                    $last_userinfoid = $db->getLastInsertId;
                    var_export($last_userid);
                    var_export($last_userinfoid);

                    if($last_userid && $last_userinfoid) {
                        echo 'commit';
                        $db->db->commit();
                    } else {
                        echo '回滚了';
                        $db->db->rollBack();
   }

}

上面代码中,insertParams是某类(数据库操作类)sql执行代码,而getLastInsertId是(数据库操作类中返回的最后插入成功的数据id)

如果:

$sth = $this->db->prepare($sql);

....
bindParam(...);
....

$sth->execute();
return $this->db->lastInsertId();

直接这么写,那么就会出现标题中的错误。这时,使用$this->db->lastInsertId(),第二条没有插入成功,第一条成功了,那么第二条返回的lastInsertId就是第一条的Id

所以处理返回 lastInsertId的代码修改为:

if($sth->execute()) {
    $this->getLastInsertId = $this->db->lastInsertId();
} else {
    $this->getLastInsertId = false;
}

然后,直接获取db类中的属性getLastInsertId即可。

完!

posted @ 2016-06-02 21:37  Zell~Dincht  阅读(1035)  评论(0编辑  收藏  举报