我在Symfony 3.4应用程序中遇到问题,在该应用程序中,用户可以对其他用户的条目进行投票。它使用FOSRestBundle用于API,使用Doctrine进行数据持久化。代码很简单:
public function voteEntryAction(Request $request, ChallengeEntry $challengeEntry)
{
/** @var User */
$user = $this->getUser();
$em = $this->getDoctrine()->getManager();
$challengeVote = $em->getRepository(ChallengeVote::class)->findOneBy([
'user' => $user,
'challengeEntry' => $challengeEntry,
]);
if ($challengeVote) {
throw new BadRequestHttpException('User has already voted for this challenge entry.');
}
$challengeVote = new ChallengeVote();
$challengeVote
->setUser($user)
->setChallengeEntry($challengeEntry)
;
$form = $this->createForm(ChallengeVoteType::class, $challengeVote);
$form->submit($request->request->all());
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($challengeVote);
// updates the statistics
$user->addGivenChallengeVote($challengeVote); // <=== here and the next line are the problematic lines
$challengeEntry->getUser()->addReceivedChallengeVote($challengeVote); // <=== here and the previous line are the problematic lines
// SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction
$em->flush();
return $user;
}
return $this->view($data, Response::HTTP_BAD_REQUEST);
}
有时我会收到此错误:
SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction
我能够重现此错误,它发生在[[当两个用户同时投票时。这是因为每个用户都在更新彼此。我该如何解决?
我尝试了以下选项:尝试解决方案1
我在另一个用户的更新之前添加了另一个$em->flush
。并非最佳,但似乎可以工作:// updates the statistics
$user->addGivenChallengeVote($challengeVote);
$em->flush();
// adds a different flush for the other user in order to avoid the following error:
// SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction
$challengeEntry->getUser()->addReceivedChallengeVote($challengeVote);
$em->flush();
我已经尝试捕获尝试解决方案2
RetryableException
并再次执行刷新,但收到错误The EntityManager is closed
。尝试解决方案3
我尝试使用$em->resetManager()
重置EntityManager,但随后所有实体都被分离,甚至用户也被认为是新用户。 这里是一篇很棒的博客文章,例如:link