后台:我有一个处理数据库查询的类。问题是,只有在需要时才会执行查询,因此有时可能会离创建的位置有点远。现在,如果包装的SQL查询失败,就很难将其追溯到它的起源。
现在的想法是:在创建包装器时,我将创建一个通用异常对象(它给我回溯跟踪和所有东西)。当在实际执行过程中发生某些事情时,可以使用预先生成的异常在调试时查找问题的来源。
这不可避免地导致了一个问题:预先生成Exception对象的代价有多大?这样做是明智的吗?如何调试延迟的SQL执行?
为了澄清这个过程,下面是一些伪代码:
$list = new QueryWrapper("SELECT ...");
$list->setPage(5);
// Later...
foreach ($list as $entry) { ... }只有当前端实际访问$list时,查询才会执行。
更新:这里是一个极简的实现:
public function __construct($query, ... $params = array()) {
...
$this->createTrace = new \Exception();
}
// called by the Iterator's rewind()
private function runQuery() {
try {
// execute query;
}
catch(\Exception $e) {
throw new \Exception(
sprintf(
'Exception thrown after SQL error (created as %s)',
$this->createTrace->getTraceAsString()
),
0, $e
);
}
}发布于 2011-07-18 14:31:45
实例化一个稍后可能抛出的异常,听起来是一个非常不寻常的想法,可能不是我所期望的那样。我是说,正常的情况是不要抛出一个例外。因此,大多数情况下,您将创建一个异常,很可能永远不会抛出/使用。
程序流中稍后抛出的异常将给您提供堆栈跟踪,因此在我看来:不要麻烦,也不要这样做。
发布于 2011-07-18 14:25:55
在生产环境中,我认为性能“损失”是可以忽略的,因为创建Exception对象与创建任何类是一样的,这几乎没有任何影响。
不过,我不确定这是否是解决你问题的正确方法。这就是你想做的吗?
$list = new QueryWrapper("SELECT ...");
$list->exception = new Exception();发布于 2016-10-14 22:03:50
一个简单的3v4l测试:
https://3v4l.org/ACHS0/perf#output
差别似乎很小(在3v4l.org硬件上,每创建一个异常大约有1-10 us --如果您每次请求运行几十个查询,这还不到1毫秒,即使对于高性能的web应用程序也不适用)。
https://stackoverflow.com/questions/6734391
复制相似问题