不知道分析的对不对——阅读 Laravel 5.5 中的事务部分源码做的小测试?
通过阅读laravel 事务部分源码,我做了一个测试
- 第一步:开启一个事务
此时 $this->transactions =0,正常开启一个事物 ,$this->transactions的值加一 -
第二步: beginTransaction() 再次开启一个事物
此时 $this->transactions =1,mysql此时会创建一个名字是trans_2的savepoint,这个savepoint可以理解为一个事务记录点,当需要回滚时可以只回滚到这个点。$this->transactions的值再加一public function beginTransaction() { $this->createTransaction(); $this->transactions++; $this->fireConnectionEvent('beganTransaction'); } 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(); } }
- 第三步: commit()
因为此时 $this->transactions =2,不会进行事物的提交
此时 将$this->transactions值减1,则$this->transactions值为1public function commit() { if ($this->transactions == 1) { $this->getPdo()->commit(); } $this->transactions = max(0, $this->transactions - 1); $this->fireConnectionEvent('committed'); }
-
第四步: rollBack()
因为先将 $this->transactions值减 1,$this->transactions值为0 所以会执行正常的回滚public function rollBack($toLevel = null) { $toLevel = is_null($toLevel) ? $this->transactions - 1 : $toLevel; if ($toLevel < 0 || $toLevel >= $this->transactions) { return; } $this->performRollBack($toLevel); $this->transactions = $toLevel; $this->fireConnectionEvent('rollingBack'); }
protected function performRollBack($toLevel) { if ($toLevel == 0) { $this->getPdo()->rollBack(); } elseif ($this->queryGrammar->supportsSavepoints()) { $this->getPdo()->exec( $this->queryGrammar->compileSavepointRollBack('trans'.($toLevel + 1)) ); } }
我这里有一个疑问 它到底回滚到哪了????
这是我的初步想法:
1) 是到 trans_2的savepoint点吗,如果是的话,那么我再开完第一个事务后执行一个updte,再开另一个事务,那么回滚到trans_2的savepoint点,则这个update应该没有受到影响呀,我通过实际的测试发现,update也被回滚了。
2) 还有就是mysql 遇到beginTransaction() 会进行隐性提交的,那么我的这个update也不应该受到影响啊
老哥,mysql的MyISAM存储引擎不支持事物的, 你的数据库用的什么引擎啊?
mysql 5.7 InnoDB
你是不是找错class了?
laravel中mysql的driver默认是“mysql”,指的是pdo_mysql,而用的Connection是Doctrine\DBAL\Connection,你看看这里面的事务code
我刚又打印了一下,发现他确实走的是
laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php
这个类下的方法,
我查了一下5.1版本的时候确实走的是
laravel/framework/src/Illuminate/Database/Connection.php
这个类下的方法。
这两个版本虽然写法上变了,但是实质的东西还是一样的,都会有我上面说的这个疑问存在。