From d08ae3671a2a38c235aa9d6941be498b5b30f70a Mon Sep 17 00:00:00 2001 From: yunwuxin <448901948@qq.com> Date: Wed, 15 Jun 2016 11:03:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E4=BA=8B=E5=8A=A1=E5=B5=8C?= =?UTF-8?q?=E5=A5=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/think/db/Connection.php | 99 +++++++++++++++++---------- library/think/db/connector/Mysql.php | 4 ++ library/think/db/connector/Oracle.php | 4 ++ library/think/db/connector/Pgsql.php | 4 ++ library/think/db/connector/Sqlite.php | 4 ++ 5 files changed, 80 insertions(+), 35 deletions(-) diff --git a/library/think/db/Connection.php b/library/think/db/Connection.php index aa8e221c..f9ea922c 100644 --- a/library/think/db/Connection.php +++ b/library/think/db/Connection.php @@ -36,8 +36,6 @@ abstract class Connection protected $numRows = 0; // 事务指令数 protected $transTimes = 0; - // 事务标识 - protected $transLabel = ''; // 错误信息 protected $error = ''; @@ -520,65 +518,67 @@ abstract class Connection * @access public * @param callable $callback 数据操作方法回调 * @return mixed + * @throws PDOException + * @throws \Exception + * @throws \Throwable */ public function transaction($callback) { - $label = microtime(true); - $this->startTrans($label); + $this->startTrans(); try { $result = null; if (is_callable($callback)) { - $result = call_user_func_array($callback, []); + $result = call_user_func_array($callback, [$this]); } - $this->commit($label); + $this->commit(); return $result; } catch (\Exception $e) { $this->rollback(); throw $e; + } catch (\Throwable $e) { + $this->rollback(); + throw $e; } } /** * 启动事务 * @access public - * @param string $label 事务标识 * @return bool|null */ - public function startTrans($label = '') + public function startTrans() { $this->initConnect(true); if (!$this->linkID) { return false; } - //数据rollback 支持 - if (0 == $this->transTimes) { - $this->transLabel = $label; + ++$this->transTimes; + + if ($this->transTimes == 1) { $this->linkID->beginTransaction(); + } elseif ($this->transTimes > 1 && $this->supportSavepoint()) { + $this->linkID->exec( + $this->parseSavepoint('trans' . $this->transTimes) + ); } - $this->transTimes++; - return; } /** * 用于非自动提交状态下面的查询提交 * @access public - * @param string $label 事务标识 * @return boolean * @throws PDOException */ - public function commit($label = '') + public function commit() { $this->initConnect(true); - if ($this->transTimes > 0 && $label == $this->transLabel) { - try { - $this->linkID->commit(); - $this->transTimes = 0; - } catch (\PDOException $e) { - throw new PDOException($e, $this->config, $this->queryStr); - } + + if ($this->transTimes == 1) { + $this->linkID->commit(); } - return true; + + --$this->transTimes; } /** @@ -590,15 +590,45 @@ abstract class Connection public function rollback() { $this->initConnect(true); - if ($this->transTimes > 0) { - try { - $this->linkID->rollback(); - $this->transTimes = 0; - } catch (\PDOException $e) { - throw new PDOException($e, $this->config, $this->queryStr); - } + + if ($this->transTimes == 1) { + $this->linkID->rollBack(); + } elseif ($this->transTimes > 1 && $this->supportSavepoint()) { + $this->linkID->exec( + $this->parseSavepointRollBack('trans' . $this->transTimes) + ); } - return true; + + $this->transTimes = max(0, $this->transTimes - 1); + } + + /** + * 是否支持事务嵌套 + * @return bool + */ + protected function supportSavepoint() + { + return false; + } + + /** + * 生成定义保存点的SQL + * @param $name + * @return string + */ + protected function parseSavepoint($name) + { + return 'SAVEPOINT ' . $name; + } + + /** + * 生成回滚到保存点的SQL + * @param $name + * @return string + */ + protected function parseSavepointRollBack($name) + { + return 'ROLLBACK TO SAVEPOINT ' . $name; } /** @@ -614,14 +644,13 @@ abstract class Connection return false; } // 自动启动事务支持 - $label = microtime(true); - $this->startTrans($label); + $this->startTrans(); try { foreach ($sqlArray as $sql) { - $result = $this->execute($sql); + $this->execute($sql); } // 提交事务 - $this->commit($label); + $this->commit(); } catch (\PDOException $e) { $this->rollback(); return false; diff --git a/library/think/db/connector/Mysql.php b/library/think/db/connector/Mysql.php index b9d910d3..5f83f496 100644 --- a/library/think/db/connector/Mysql.php +++ b/library/think/db/connector/Mysql.php @@ -110,4 +110,8 @@ class Mysql extends Connection } return $result; } + + protected function supportSavepoint(){ + return true; + } } diff --git a/library/think/db/connector/Oracle.php b/library/think/db/connector/Oracle.php index 1e2a4372..f50ec5f1 100644 --- a/library/think/db/connector/Oracle.php +++ b/library/think/db/connector/Oracle.php @@ -154,4 +154,8 @@ class Oracle extends Connection { return []; } + + protected function supportSavepoint(){ + return true; + } } diff --git a/library/think/db/connector/Pgsql.php b/library/think/db/connector/Pgsql.php index 350803a8..161165ac 100644 --- a/library/think/db/connector/Pgsql.php +++ b/library/think/db/connector/Pgsql.php @@ -93,4 +93,8 @@ class Pgsql extends Connection { return []; } + + protected function supportSavepoint(){ + return true; + } } diff --git a/library/think/db/connector/Sqlite.php b/library/think/db/connector/Sqlite.php index cac8c352..d8f63f81 100644 --- a/library/think/db/connector/Sqlite.php +++ b/library/think/db/connector/Sqlite.php @@ -92,4 +92,8 @@ class Sqlite extends Connection { return []; } + + protected function supportSavepoint(){ + return true; + } }