更新:我发现了问题,but I don't understand why它存在但我不知道如何修复它。
实际上,我会检查当前处理Job
是否是重试的:
if ($job->isRetry()) {
$this->entityManager->persist($job->getRetryOf());
$this->ioWriter->noteLineNoBg(sprintf(
'[%s] Job "%s" on Queue "%s": this is a retry of original process #%s.',
$now->format('Y-m-d H:i:s'), $job->getId(), $job->getQueue(), $job->getRetryOf()->getId()
));
}
所以,此时,重试Job
已加载,当我更新当前Job
时,已重试的已经补充,但未经实体经理管理!为什么不呢?这是否意味着每次我致电Job#isRetry()
时,我都会再次坚持重试Job
?
更多:如果我再次坚持,我在数据库中有重复的条目!
在那些日子里在StackOverflow上阅读,我已经阅读了另一个与我有类似问题的开发者问题:他讲述了使用两个不同的实体管理器:如何验证是否使用了实体管理器我的实体是否与我的服务一样?
这是我的原始问题
我有一个代表要执行的命令的Job
实体。
现在,如果命令失败,我会创建一个新的Job
实体,重试先前失败的Job
。
问题是我收到错误:
通过这种关系找到了一个新的实体 ' SerendipityHQ \包\ CommandsQueuesBundle \实体\作业#retriedBy'那 未配置为级联实体的持久操作:3。到 解决此问题:显式调用EntityManager#persist()on 这个未知的实体或配置级联持久存在此关联 映射例如@ManyToOne(..,cascade = {" persist"})。
我知道,这是StackOverflow上一个非常常见的问题:我已经搜索了几天的解决方案,但没有人在one-to-one
自引用实体中出现此错误。所以他们的解决方案不适合我。
/**
* Basic properties and methods o a Job.
*
* @ORM\Entity(repositoryClass="SerendipityHQ\Bundle\CommandsQueuesBundle\Repository\JobRepository")
* @ORM\Table(name="queues_scheduled_jobs")
*/
class Job
{
...
/**
* @var Job $retryOf If this Job is a retry of another job, here there is the Job of which this is the retry
*
* @ORM\OneToOne(targetEntity="SerendipityHQ\Bundle\CommandsQueuesBundle\Entity\Job", inversedBy="retriedBy")
* @ORM\JoinColumn(name="retry_of", referencedColumnName="id")
*/
private $retryOf;
/**
* @var Job $retriedBy
*
* @ORM\OneToOne(targetEntity="SerendipityHQ\Bundle\CommandsQueuesBundle\Entity\Job", mappedBy="retryOf")ì
*/
private $retriedBy;
...
}
第一个问题:这个maping是否正确?它有任何错误吗?
我已经尝试了所有可能的事情:在使用时尝试保留两个实体,分离然后重新保留,刷新,提取EAGER
,同时设置retryOf
和retriedBy
setRetryOf()
(这个是拥有的一面,对吗?)...也使用级联选项(但这会复制数据库中的实体而不是更新已存在的实体)任何东西!问题依然存在。
当我从数据库加载实体时,它似乎就出现了。
让我们看一下这个日志:
[INFO] [2017-02-14 15:30:42] Job "1" on Queue "default": Initializing the process.
"Marking job 1 with status pending"
[INFO] Checking 1 running jobs...
"Start marking 1 as retried"
"Marking job 1 with status retried"
[✖] [2017-02-14 15:30:57] Job "1" on Queue "default": Process failed.
! [NOTE] [2017-02-14 15:30:57] Job "1" on Queue "default": Retry with Job "3" (Attempt #1/3).
[INFO] [2017-02-14 15:31:00] Job "3" on Queue "default": Initializing the process.
! [NOTE] [2017-02-14 15:31:00] Job "3" on Queue "default": this is a retry of original process #1.
"Marking job 3 with status pending"
[INFO] Checking 1 running jobs...
"Start marking 3 as retried"
"Marking job 3 with status retried"
[✖] [2017-02-14 15:31:17] Job "3" on Queue "default": Process failed.
! [NOTE] [2017-02-14 15:31:17] Job "3" on Queue "default": Retry with Job "4" (Attempt #2/3).
[INFO] [2017-02-14 15:31:19] Job "4" on Queue "default": Initializing the process.
! [NOTE] [2017-02-14 15:31:19] Job "4" on Queue "default": this is a retry of original process #3.
"Marking job 4 with status pending"
Exception: A new entity was found through the relationship 'SerendipityHQ\Bundle\CommandsQueuesBundle\Entity\Job#retriedBy' that was not configured to cascade persist operations for entity: 3. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}).
见最后几行:
[INFO] [2017-02-14 15:31:19] Job "4" on Queue "default": Initializing the process.
! [NOTE] [2017-02-14 15:31:19] Job "4" on Queue "default": this is a retry of original process #3.
"Marking job 4 with status pending"
在此阶段,我刚刚从数据库中检索了Job
#4,并尝试将其状态从new
更新为pending
。
此时,我收到了属性为retriedBy
的非托管实体的实体#3的错误。但是这个实体正在更新Job
#4!怎么可能找不到它?而且,如果我再次坚持,错误仍然存在。
我真的不知道在哪里寻找这个bug。有人能帮助我吗?
更多代码
当我尝试将new
作业的状态更新为pending
并且此更改Job
同时包含retryOf
和retriedBy
属性时,会出现问题集。
要更改Job
的状态,请使用课程JobsMarker
。
错误在方法markJobAsPending()
处触发:
// Utils\JobsMarker.php
public function markJobAsPending(Job $job, array $info, Daemon $daemon)
{
$this->markJob($job, Job::STATUS_PENDING, $info, $daemon);
}
实体管理器是一样的,我在$em->flush()
处理过程中多次调用Job
来更新Job
的状态(原因可能是这个?这真的很奇怪!)。
流程是这样的:
Job
to process from the database; aborted
或as pending
; 当Job
退出时,我会将其标记为相应的状态:如果失败and can be retried,I create a new Job
:
// Util \ JobsMarker.php public function markJobAsRetried(Job $ job,array $ info) { //创建一个新的重试作业 $ retryJob = $ job-> createRetryJob();
// Set this retry Job as a retry of the original one
$retryJob->setRetryOf($job);
$this->entityManager->persist($retryJob);
$this->markJobAsClosed($job, Job::STATUS_RETRIED, $info);
return $retryJob;
}
那么,会发生什么?
pending
(`Utils \ JobsMarker); pending
我收到有关未管理实体的例外情况。而且我真的不明白为什么!希望这能帮助你帮助我!