0

1)控制器代码(Symfony2框架):

    $em = $this->getDoctrine()->getEntityManager();

    // get latest toplist
    $last = $em->getRepository('RadioToplistBundle:Toplist')->findOneBy(
      array('number' => 'DESC')
    );

    // get current year and week of the year
    $week = date('W');
    $year = date('Y');

    // if:
    //   [case 1]: $last is null, meaning there are no toplists in the database
    //   [case 2]: $last->getYear() or $last->getWeek() do not match current
    //             year and week number, meaning that there are toplists in the
    //             database, but not for current week
    // then:
    //   create new toplist entity (for current week of current year)
    // else:
    //   do nothing (return)

    if($last && $last->getYear() == $year && $last->getWeek() == $week)
      return;
    else {
      $new = new Toplist();
      $new->setYear($year);
      $new->setWeek($week);
      $em->persist($new);
      $em->flush();
    }

此代码随每个请求执行以查看顶级列表结果(前端)或顶级列表列表(后端)。每当有人想要访问 toplist 时,我们首先检查是否应该创建一个新的 toplist 实体(用于新的一周)。

2)问题是:

有没有可能:

  • 用户 A 于周一 00:00:01 访问 mydomain.com/toplist -> 代码应生成新实体
  • 服务器变慢了,他需要 3 秒来执行代码
  • 所以新的顶级列表实体在星期一 00:00:04 保存到数据库
  • 用户 B 在星期一 00:00:02 访问 mydomain.com/toplist
  • 在 00:00:02,toplist 尚未保存在数据库中,因此 UserB 的请求触发代码创建另一个 toplist 实体

所以.. 几秒钟后,我们有 2 个本周的顶级实体。

这可能吗?

我应该如何防止这种情况?

4

1 回答 1

2

对的,这是可能的。您应该在基于 db 值(而不是存储在 db 中)执行计算时使用锁。

在教义的文档中阅读更多关于锁的信息:锁定支持

于 2012-07-01T09:22:42.833 回答