ZF2、Oracle、SlmQueueDoctrine、ClearObjectManagerStrategy不起作用



我有一个ZF2项目,配置如下。它使用的是条令ORM和SlmQueue。由于SlmQueue不支持我们的命名约定和oracle数据库,因此我们定制了SlmQueueDoctrine。

我怀疑我的作业没有使用ClearObjectManagerStrategy,并且在执行单个作业之前没有清除ObjectManager。

它不反映队列启动后对数据库的修改。但如果我终止队列守护进程并重新启动,它会选择新的值。

如何在执行单个作业之前实现ClearObjectManagerStrategy并清除ObjectManager?

我试过很多次都没有成功。

composer.json

{
    "repositories": [
        {
            "url": "https://github.com/pradeep-sanjaya/doctrine-extensions.git",
            "type": "git"
        }
    ],
    "require": {
        "php": ">=5.3.3",
        "zendframework/zendframework": "2.3.3",
        "doctrine/doctrine-orm-module": "0.7.*",
        "pradeep-sanjaya/doctrine-extensions": "dev-master",
        "spoonx/sxmail": "1.4.*",
        "slm/locale": "dev-master",
        "imagine/Imagine": "0.6.*",
        "tecnick.com/tcpdf": "dev-master",
        "slm/queue": "0.4.*",
        "slm/queue-doctrine": "0.4.*"
    }
}

config/autoload/slm_queue.local.php

<?php
return array(
    'slm_queue' => array(
        'queue_manager' => array(
            'factories' => array(
                'doctrineQueue' => 'SlmQueueDoctrineFactoryDoctrineQueueFactory'
            ),
        ),
        'job_manager' => array(
            'factories' => array(
                'ReportJobRank' => 'ReportJobRankFactory',
            ),
            'shared' => array(
                'ReportJobRank' => false
            ),
        ),
        'queues' => array(
            'doctrineQueue' => array(
                'table_name' => 'IOQUEUE'
            )
        )
    )
);
?>

module/Report/src/Report/Job/Rank.php

<?php
namespace ReportJob;
use DoctrineModulePersistenceObjectManagerAwareInterface;
use DoctrineModulePersistenceProvidesObjectManager as ProvidesObjectManagerTrait;
use SlmQueueJobAbstractJob;
use ApplicationEntityReport;
use ApplicationLogLoggerAwareInterface;
use ApplicationLogLoggerAwareTrait;
use ApplicationServiceReportService;
class Rank extends AbstractJob implements ObjectManagerAwareInterface, LoggerAwareInterface
{
    use LoggerAwareTrait;
    use ProvidesObjectManagerTrait;
    /**
     * @var ReportService
     */
    protected $reportService;
    /**
     * @var array
     */
    protected $reportId = array();
    public function setReportService(ReportService $reportService)
    {
        $this->reportService = $reportService;
    }
    /**
     * Execute the job
     *
     * @return void
     */
    public function execute()
    {
        //clear object manager does not work
        //$om = $this->getObjectManager();
        //$om->clear();
        $content = $this->getContent();
        $this->setReportId($content['reportId']);
        if (!empty($this->reportId)) {
            try {
                if (is_array($this->reportId)) {
                    foreach ($this->reportId as $reportId) {
                        $this->updateRank($reportId);
                    }
                    unset($reportId);
                } else {
                    $this->updateRank($this->reportId);
                }
            } catch (Exception $exception) {
                echo "Exception message is {$exception->getMessage()} n";
            }
        }
    }
    private function updateRank($reportId)
    {
        /* @var $report Report */
        $report = $this->reportService->getReport($reportId);
        $this->logInfo(print_r($report, true)); // this always return older db values, the values before it start queue deamon
        if (!$report instanceof Report) {
            return;
        }
        if (empty($rankData)) {
            return;
        }
        //more codes, application related logics
        $this->reportService->updateReportEntity($report);
    }
    private function setReportId($reportId)
    {
        if (is_numeric($reportId)) {
            $this->reportId = array($reportId);
        } elseif (is_array($reportId)) {
            $this->reportId = $reportId;
        } else {
            throw new Exception('Expects reportId as int or array');
        }
    }
}

如果你的意思是它没有完全清除,那么显然这不是一个bug,而是预期的行为。

您可以查看文档第7.5章。了解调用clear方法的行为:

当调用EntityManager#clear()时,当前由EntityManager实例管理的所有实体都将分离。

您的评论中,您说过"它不会刷新对象管理器和当前事务"。这不是一个你可以期望调用clear的操作。根据文件,分离会导致以下操作:

应用于实体X的分离操作的语义如下:

  • 如果X是托管实体,则分离操作会使其分离。如果从X到这些其他实体的关系是用cascade=detach或cascade=ALL映射的,则分离操作级联到X引用的实体(请参见"传递持久性")。以前引用X的实体将继续引用X
  • 如果X是新实体或已分离实体,则分离操作会忽略它
  • 如果X是已删除的实体,则分离操作级联到X引用的实体,如果从X到这些其他实体的关系映射为cascade=detach或cascade=ALL(请参见"传递持久性")。以前引用X的实体将继续引用X

最新更新