?从今天开始,陆续给大家点评一些垃圾代码。但愿对大家有帮助。
先看一段代码:
?
class="php"> /**
* 启动事务
* @access public
* @return bool|mixed
* @throws \Exception
*/
public function startTrans()
{
$this->initConnect(true);
if (!$this->linkID) {
return false;
}
++$this->transTimes;
try {
if (1 == $this->transTimes) {
$this->linkID->beginTransaction();
} elseif ($this->transTimes > 1 && $this->supportSavepoint()) {
$this->linkID->exec(
$this->parseSavepoint('trans' . $this->transTimes)
);
}
} catch (\PDOException $e) {
if ($this->isBreak($e)) {
return $this->close()->startTrans();
}
throw $e;
} catch (\Exception $e) {
if ($this->isBreak($e)) {
return $this->close()->startTrans();
}
throw $e;
} catch (\Error $e) {
if ($this->isBreak($e)) {
return $this->close()->startTrans();
}
throw $e;
}
}
?
?
? ? ?这是国内某开源十余年的知名框架的核心代码。
? ? ?很明显,虽然有什么try catch结构,但无法遮掩其代码功底之差,思路的初级。
? ? ?第一点,把数据库链接与事务搅在的一起。虽然用华丽的链式操作,但是,反而弄巧成拙。
? ? ?为什么这么说,因为,链接就是在此类中处理的。此类中就有函数:
? ? ?abstract protected function parseDsn($config);? 所以,这完全违反了单一职责原则。
? ? ?当然,写在一起,处理得好就算了。可是,万万没有想到的是,在catch中并没有完全逃脱。
?
? 因为,这一行:return $this->close()->startTrans();
?
? 不是说,这一行重新开始有问题,但是,本质上,它根本没有重新开始,因为,
?
? 前面有了什么?这一行:
?
? ++$this->transTimes;??
?
? 这是在try catch之外的,本来就是一个记数器。可是,写这段代码的人可参没有想到, 你还没有beginTransaction 成功,你就把计数器给加了。 而出错时,并没有处理这个计数器。所以,这个框架数据库频繁出错,大家一定明白错在何处了。
?
? 再看另一个代码:
/**
* Start a new database transaction.
*
* @return void
* @throws \Exception
*/
public function beginTransaction()
{
$this->createTransaction();
$this->transactions++;
$this->fireConnectionEvent('beganTransaction');
}
/**
* Create a transaction within the database.
*
* @return void
*/
protected function createTransaction()
{
if ($this->transactions == 0) {
try {
$this->getPdo()->beginTransaction();
} catch (Exception $e) {
$this->handleBeginTransactionException($e);
}
} elseif ($this->transactions >= 1 && $this->queryGrammar->supportsSavepoints()) {
$this->createSavepoint();
}
}
?
? ? 这段代码思路就非常清晰,并且,代码简单易懂。 即monospace;">beginTransaction未成功之前,什么都不做。
?当然,这是Laravel框架的代码。二者肯定不是一个级别!?