源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

PHP中实现MySQL嵌套事务的两种解决方案

  • 时间:2020-10-17 09:47 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:PHP中实现MySQL嵌套事务的两种解决方案
[b]一、问题起源[/b] 在MySQL的[url=http://dev.mysql.com/doc/refman/5.0/en/implicit-commit.html]官方文档[/url]中有明确的说明不支持嵌套事务:
[url=http://dev.mysql.com/doc/refman/5.0/en/savepoint.html]savepoint[/url],这个savepoint可以理解为一个事务记录点,当需要回滚时可以只回滚到这个点。 然后看下rollBack函数:
[u]复制代码[/u] 代码如下:
public function rollBack() {     if ($this->_transactionNestingLevel == 0) {         throw ConnectionException::noActiveTransaction();     }     if ($this->_transactionNestingLevel == 1) {         $this->_transactionNestingLevel = 0;         $this->_conn->rollback();         $this->_isRollbackOnly = false;     } else if ($this->_nestTransactionsWithSavepoints) {         $this->rollbackSavepoint($this->_getNestedTransactionSavePointName());         --$this->_transactionNestingLevel;     } else {         $this->_isRollbackOnly = true;         --$this->_transactionNestingLevel;     } }
可以看到处理的方式也很简单,如果level是1,直接rollback,否则就回滚到前面的savepoint。 然后我们继续看下commit函数:
[u]复制代码[/u] 代码如下:
public function commit() {     if ($this->_transactionNestingLevel == 0) {         throw ConnectionException::noActiveTransaction();     }     if ($this->_isRollbackOnly) {         throw ConnectionException::commitFailedRollbackOnly();     }     if ($this->_transactionNestingLevel == 1) {         $this->_conn->commit();     } else if ($this->_nestTransactionsWithSavepoints) {         $this->releaseSavepoint($this->_getNestedTransactionSavePointName());     }     --$this->_transactionNestingLevel; }
算了,不费口舌解释这段了吧 :) [b]三、laravel的解决方案[/b] laravel的处理方式相对简单粗暴一些,我们先来看下创建事务的操作:
[u]复制代码[/u] 代码如下:
public function beginTransaction() {     ++$this->transactions;     if ($this->transactions == 1)     {         $this->pdo->beginTransaction();     } }
感觉如何?so easy吧?先判断当前有几个事务,如果是第一个,ok,事务开始,否则就啥都不做,那么为啥是啥都不做呢?继续往下看rollBack的操作:
[u]复制代码[/u] 代码如下:
public function rollBack() {     if ($this->transactions == 1)     {         $this->transactions = 0;         $this->pdo->rollBack();     }     else     {         --$this->transactions;     } }
明白了吧?只有当当前事务只有一个的时候才会真正的rollback,否则只是将计数做减一操作。这也就是为啥刚才说laravel的处理比较简单粗暴一些,在嵌套的内层里面实际上是木有真正的事务的,只有最外层一个整体的事务,虽然简单粗暴,但是也解决了在内层新建一个事务时会造成commit的问题。原理就是这个样子了,为了保持完整起见,把commit的代码也copy过来吧!
[u]复制代码[/u] 代码如下:
public function commit() {     if ($this->transactions == 1) $this->pdo->commit();     --$this->transactions; }
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部