如何检测 MySQL 中的隐式提交?

Posted

技术标签:

【中文标题】如何检测 MySQL 中的隐式提交?【英文标题】:How to detect implicit commit in MySQL? 【发布时间】:2014-03-19 21:22:18 【问题描述】:

我想知道是否有可能检测到由隐式提交或否导致的损坏事务。 目前我不知道如何检查我的应用程序中的事务是否在没有隐式提交的情况下工作。我也看不到我的更改是否不会导致隐式提交。

看起来最简单的控制方法是强制 mysql 抛出错误而不是隐式提交,但我不知道如何配置它。

有时很难在代码中看到问题,因此 MySQL 错误可能是保护事务的有效方法。

下面的示例将显示可以隐藏多少隐式提交..

隐式提交的代码:

public function loadDataToDb(XMLReader $productXML)

    $this->stats = $this->getProductImporter()->initStats();

    while ($productXML->read()) 

        if ($productXML->nodeType == XMLReader::ELEMENT && $productXML->name == 'product') 
            $doc = new DOMDocument('1.0', 'UTF-8');
            $product = simplexml_import_dom($doc->importNode($productXML->expand(), true));
            $this->getDBConnection()->beginTransaction();
            try 
                $this->getStorage()->addProduct($product);
                $this->getDBConnection()->commit();
                $this->stats['valid_skus'][trim($product->sku)] = true;
             catch (Exception $e) 
                $this->getDBConnection()->rollBack();
                $this->stats['invalid_skus'][trim($product->sku)] = true;
                $this->productLog('Product ' . $product->sku . ' skipped:' . $e);
            
        
    

固定代码:

public function loadDataToDb(XMLReader $productXML)

    $this->stats = $this->getProductImporter()->initStats();
    $storage = $this->getStorage();

    while ($productXML->read()) 

        if ($productXML->nodeType == XMLReader::ELEMENT && $productXML->name == 'product') 
            $doc = new DOMDocument('1.0', 'UTF-8');
            $product = simplexml_import_dom($doc->importNode($productXML->expand(), true));
            $this->getDBConnection()->beginTransaction();
            try 
                $storage->addProduct($product);
                $this->getDBConnection()->commit();
                $this->stats['valid_skus'][trim($product->sku)] = true;
             catch (Exception $e) 
                $this->getDBConnection()->rollBack();
                $this->stats['invalid_skus'][trim($product->sku)] = true;
                $this->productLog('Product ' . $product->sku . ' skipped:' . $e);
            
        
    

解释:在第一次调用函数 $this->getStorage() 时,它会创建 Storage 对象,该对象在它的 __constructor 中执行截断。所以事务被破坏了,不调试就无法检测到它。

在这种情况下,pdo 异常会有很大帮助。

【问题讨论】:

【参考方案1】:

如果你在正常异常之前使用另一个catch块并捕获一个PDO异常?

public function loadDataToDb(XMLReader $productXML)

$this->stats = $this->getProductImporter()->initStats(); $storage = $this->getStorage();

while ($productXML->read()) 

    if ($productXML->nodeType == XMLReader::ELEMENT && $productXML->name == 'product') 
        $doc = new DOMDocument('1.0', 'UTF-8');
        $product = simplexml_import_dom($doc->importNode($productXML->expand(), true));
        $this->getDBConnection()->beginTransaction();
        try 
            $storage->addProduct($product);
            $this->getDBConnection()->commit();
            $this->stats['valid_skus'][trim($product->sku)] = true;
         catch (PDOException $pdo) 
            $this->getDBConnection()->rollBack();
            $this->stats['invalid_skus'][trim($product->sku)] = true;
            $this->productLog('Product database error:  ' . $product->sku . ' skipped:' . $e);
         catch (Exception $e) 
            $this->productLog('Product error:'. $e);
        
    

【讨论】:

没有pdo异常

以上是关于如何检测 MySQL 中的隐式提交?的主要内容,如果未能解决你的问题,请参考以下文章

Java 中的隐式转换是如何工作的?

Java 中的隐式转换是如何工作的?

如何禁用typescript中的隐式导入

Mysql中的隐式转换

如何将参数传递给 Laravel 5 中的隐式控制器?

如何避免条件表达式中咖啡脚本中的隐式“返回”?