【问题标题】:Doctrine query iterate not working on MS SQL Server - New transaction is not allowedDoctrine 查询迭代在 MS SQL Server 上不起作用 - 不允许新事务
【发布时间】:2019-05-31 13:51:47
【问题描述】:

我正在尝试迭代结果并使用实体管理器将其删除,如https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/batch-processing.html#iterating-results中所述

但是,在调用 flush() 时出现以下错误:

PHP 致命错误: Uncaught Doctrine\DBAL\Driver\SQLSrv\SQLSrvException: SQLSTATE [42000, 3988]: [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]不允许新事务,因为还有其他线程在会话中运行。在 D:\inetpub\wwwroot\vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\SQLSrv\SQLSrvException.php:54

<?php

$batchSize = 20;
$i = 0;

$q = $em->createQuery('select u from MyProject\Model\User u WHERE credit < :minCredit');
$q->setParameter('minCredit', 20);

$iterableResult = $q->iterate();
while (($row = $iterableResult->next()) !== false) {
    $em->remove($row[0]);
    if (($i % $batchSize) === 0) {
        $em->flush();
        $em->clear();
    }
    ++$i;
}
$em->flush();

【问题讨论】:

    标签: php sql-server pdo doctrine-orm doctrine


    【解决方案1】:

    问题是因为 SQL Server 在迭代准备好的语句时无法开始新事务。

    解决方案是开始一个包含准备好的语句的事务,然后在更改所有对象后提交。

    <?php
    
    $conn = $em->getConnection();
    
    $batchSize = 20;
    $i = 0;
    
    $q = $em->createQuery('select u from MyProject\Model\User u WHERE credit < :minCredit');
    $q->setParameter('minCredit', 20);
    
    $conn->beginTransaction();
    
    try {
        $iterableResult = $q->iterate();
        while (($row = $iterableResult->next()) !== false) {
            $em->remove($row[0]);
            if (($i % $batchSize) === 0) {
                $em->flush();
                $em->clear();
            }
            ++$i;
        }
        $em->flush();
    
        $conn->commit();
    } catch (\Exception $e) {
        $conn->rollBack();
        throw $e;
    }
    

    【讨论】:

      猜你喜欢
      • 2018-06-28
      • 1970-01-01
      • 1970-01-01
      • 2020-06-15
      • 1970-01-01
      • 2015-09-05
      • 1970-01-01
      • 2012-04-01
      • 1970-01-01
      相关资源
      最近更新 更多