第一,问题的根源
MySQL的正式
文档中有一个不
支持嵌套事务的明确说明:
复制代码代码如下所示:
事务不能嵌套。这是隐式的结果,也被称为以下三个方面。
但在我们的一个复杂
系统的发展必然会在不经意间交易中的嵌套事务,比如一个
函数调用B函数,函数在交易中使用事务,称为B,B的函数是一个交易,所以这是一个嵌套事务。事实上,在这点,一个事务不显著。为什么正如上面提到的,简单的
翻译是:
复制代码代码如下所示:
执行启动事务指令时,将隐式执行提交
操作。
所以我们要支持在系统架构层面事务的嵌套,嵌套的支持已经在一些成熟的ORM框架,如学说或laravel。然后我们会看看这两种框架的实现。
友好的
提示,这两个框架的函数和变量的命名更直观。虽然它们看起来很长,但它们可以通过命名直接了解这个函数或变量的含义,所以不要害怕看到一个大肿块。
二、学说解
首先,看看在理论中
创建事务的代码(干掉无关代码):
复制代码代码如下所示:
公共函数开始()
{
+ +美元-> _transactionnestinglevel;
如果(美元-> _transactionnestinglevel = = 1){
这_conn美元-> ->开始();
如果(美元-> _nesttransactionswithsavepoints){ }
这createsavepoint(美元->美元-> _getnestedtransactionsavepointname());
}
}
这个函数是一个_transactionnestinglevel
识别当前嵌套层次的第一行,如果是1,而不是嵌套的,则使用
默认的
方法在确定执行开始交易,如果超过1,那是嵌套的,她将帮助我们创建一个
保存点,保存点可以理解一个交易记录,当你需要回滚只能滚回点。
然后看看回滚函数:
复制代码代码如下所示:
公共函数回滚()
{
如果(美元-> _transactionnestinglevel = = 0){
把connectionexception::noactivetransaction();
}
如果(美元-> _transactionnestinglevel = = 1){
美元-> _transactionnestinglevel = 0;
这_conn美元-> ->回滚();
美元-> _isrollbackonly = false;
如果(美元-> _nesttransactionswithsavepoints){ }
这rollbacksavepoint(美元->美元-> _getnestedtransactionsavepointname());
——美元-> _transactionnestinglevel;
{人}
美元-> _isrollbackonly =真;
——美元-> _transactionnestinglevel;
}
}
你可以看到,
处理的方式也很简单,如果是1级,直接回复,否则回滚到以前的保存点。
然后我们继续研究提交函数:
复制代码代码如下所示:
公共函数提交()
{
If ($this->_transactionNestingLevel = = 0) {
把connectionexception::noactivetransaction();
}
如果(美元-> _isrollbackonly){
把connectionexception::commitfailedrollbackonly();
}
如果(美元-> _transactionnestinglevel = = 1){
这_conn美元-> ->提交();
如果(美元-> _nesttransactionswithsavepoints){ }
这releasesavepoint(美元->美元-> _getnestedtransactionsavepointname());
}
——美元-> _transactionnestinglevel;
}
来吧,别费心解释这件事:
三、laravel溶液
laravel的处理方式是比较简单和粗糙。让我们先看看创建事务的操作:
复制代码代码如下所示:
公共函数开始()
{
+ $此事务;
如果($ =事务= 1)
{
美元-> PDO ->开始();
}
}
你感觉怎么样这么简单,对吧先判断几笔交易,如果是第一次,OK,交易开始,否则没什么事,那为什么不做呢继续关注回滚操作:
复制代码代码如下所示:
公共函数回滚()
{
如果($ =事务= 1)
{
$ > >事务= 0;
美元-> ->回滚(PDO);
}
其他的
{
——$ >事务;
}
}
你明白了吗真正的回滚当前事务时,只有一个,否则只有降低到一个操作。这就是为什么laravel说处理相对比较简单粗暴,这实际上是在嵌套的内部木有真正的事务,只有一个整体交易的外层,虽然简陋,但也
解决了一个新的交易在内部造成犯罪问题。这是原则,保持完整的提交代码复制过来!
复制代码代码如下所示:
公共函数提交()
{
如果(美元->交易= = 1)(美元-> PDO ->提交);
——$ >事务;
}