Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 悲观锁理论_Php_Mysql_Symfony_Doctrine Orm - Fatal编程技术网

Php 悲观锁理论

Php 悲观锁理论,php,mysql,symfony,doctrine-orm,Php,Mysql,Symfony,Doctrine Orm,情景: 我正在Symfony2中实现一个应用程序,每五分钟运行一次命令(cronjob),该命令遍历一个MySql表,并在每个记录中,首先读取一个json_数组字段,执行一系列计算,最后在同一字段中使用新数据保存数组。此外,还有一个web应用程序,用户可以在其中编辑这些数据并将其保存在同一个表中 为了避免并发性,如果命令访问一条记录,我会设置一个悲观锁,这样,如果用户在该时刻更改数据,则必须等到事务结束并保存用户数据 但是当用户保存数据时,随机出现一个bug,用户数据没有保存,web应用程序显示

情景:

我正在Symfony2中实现一个应用程序,每五分钟运行一次命令(cronjob),该命令遍历一个MySql表,并在每个记录中,首先读取一个json_数组字段,执行一系列计算,最后在同一字段中使用新数据保存数组。此外,还有一个web应用程序,用户可以在其中编辑这些数据并将其保存在同一个表中

为了避免并发性,如果命令访问一条记录,我会设置一个悲观锁,这样,如果用户在该时刻更改数据,则必须等到事务结束并保存用户数据

但是当用户保存数据时,随机出现一个bug,用户数据没有保存,web应用程序显示以前的数据,这告诉我锁定不成功

我在symfony2命令中生成悲观锁的代码:

    foreach ($this->cisOfferMetaData as $oldCisOfferMeta) {
        // calculate budget used for each timeframe case and save it

        // begin transaction and Lock cisOfferMEta Entity
        $this->em->getConnection()->beginTransaction();
        try {
            $cisOfferMeta = $this->em->getRepository('CroboCisBundle:CisOfferMeta')->find(
                $oldCisOfferMeta->getId(),
                LockMode::PESSIMISTIC_READ
            );

            $budget = $cisOfferMeta->getBudgetOffer();

            foreach (
                generator(CisOfferMeta::getTypesArray(), CisOfferMeta::getTimeframesArray())
                as $type => $timeframe
            ) {
                if (isset($budget[$type][$timeframe]['goal'])) {
                    // if type=budget we need revenue value, if type=conversion, conversions value
                    $budget[$type][$timeframe]['used'] =
                        ($type === 'conversion')
                            ? intval($allTimeframes[$key]['conversions'][$timeframe])
                            : round($allTimeframes[$key]['revenue'][$timeframe], 2);

                    $budget[$type][$timeframe]['percent_reached'] =
                        ($budget[$type][$timeframe]['used'] == 0.0)
                            ? 0.0
                            : round(
                            $budget[$type][$timeframe]['used'] / intval($budget[$type][$timeframe]['goal']) * 100,
                            2
                        );
                }
            }

            $budget['current_conversions'] = $allTimeframes[$key]['conversions'];
            $budget['current_revenue'] = $allTimeframes[$key]['revenue'];

            $cisOfferMeta->setBudgetOffer($budget);

            $this->em->flush($cisOfferMeta);
            $this->em->getConnection()->commit();
        } catch (PessimisticLockException $e) {
            $this->em->getConnection()->rollback();
            throw $e;
        }

    }
我做错什么了吗?我猜,由于事务是在提交更改之前启动的,因此如果用户试图读取或更新数据,则必须等到锁从被阻止的实体中释放


阅读条令文档不清楚我是否应该在实体中添加版本控制最后,这段代码工作正常并产生了悲观锁,问题在于监听器在该锁之前读取数据,然后在释放锁后在没有更改的情况下刷新