Кеширование AR

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Auramel
Сообщения: 80
Зарегистрирован: 2017.11.17, 14:39
Откуда: Russia, Ufa
Контактная информация:

Кеширование AR

Сообщение Auramel »

Здравствуйте, не понимаю почему не срабатывает зависимость при кешированнии. Вот кусок кода

Код: Выделить всё

/**
     * @return int
     */
    public function getScore(): int
    {
        $sum                	  = 0;
        $dependency        	  = new DbDependency();
        $dependency->sql     = self::find()->createCommand()->getRawSql();
        $dependency->db     = self::getDb();

        $finances = self::getDb()->cache(function($db)
        {
            return FinanceModel::find()->asArray()->all();
        }, 0, $dependency);

        foreach ($finances as $finance) {
            $finance['sum'] = $this->getType($finance['type'])['sign'] . $finance['sum'];
            $sum            += $finance['sum'];
        }

        return $sum;
    }
если я правильно понял, то кешируется на время и зависимость (допустим, произошли изменения раньше времени). Я бы хотел сделать, чтобы кеш перезаписывался только когда произошли изменения в таблице в бд. Данный кусок кода работает только если время !== 0, а $dependency полностью игнорируется. Объясните, пожалуйста, в чем косяк :? :)
Nex-Otaku
Сообщения: 831
Зарегистрирован: 2016.07.09, 21:07

Re: Кеширование AR

Сообщение Nex-Otaku »

1. Запрос в DbDependency должен возвращать результат в первой, желательно единственной, строке.
Так как учитывается только первая строка выполнившегося запроса.

У вас "SELECT *" всегда одну и ту же строку возвращает в качестве первой, неважно сколько вы добавляете новых строк. Поэтому кеш считает, что ничего не изменилось, хоть вы строки и добавляете.

Что сделать? Например, заменить "SELECT *" на "SELECT COUNT(*)".

2.
Просто замечание. На всякий случай, в колбеке используйте тот коннекшен, который вам передаётся в параметрах. Иначе теоретически приложение может грохнуться, если когда-нибудь будет использоваться несколько БД.

Т.е. меняем

Код: Выделить всё

return FinanceModel::find()->asArray()->all();
на

Код: Выделить всё

return FinanceModel::find()->asArray()->all($db);
3. После исправлений в коде, не забудьте сбросить кеш, иначе так и будет глючить )
Ответить