Magento: Пользовательский запрос MySQL с блокировками, не работающими

Я пытаюсь записать функцию для ВЫБОРА наименее выбранного значения из таблицы в моей базе данных. Я делаю это путем ВЫБОРА строки и затем сразу изменения last_used поле.

Поскольку это включает ВЫБОР и ОБНОВЛЕНИЕ, я пытаюсь сделать это с блокировками. Блокировки должны гарантировать, что параллельное выполнение этого запроса не будет воздействовать на ту же строку.

Выполнения запроса, превосходные в phpMyAdmin, но сбоях в Magento. Я получаю следующую ошибку:

SQLSTATE[HY000]: General error

Ошибка происходит здесь:

#0 /var/www/virtual/magentodev.com/htdocs/lib/Varien/Db/Adapter/Pdo/Mysql.php(249): PDOStatement->fetch(2)

Вот код моей модели, включая SQL-запрос:

$write = Mage::getSingleton('core/resource')->getConnection('core_write');

$sql = "LOCK TABLES mytable AS mytable_write WRITE, mytable AS mytable_read READ;
        SELECT @val := unique_field_to_grab FROM mytable AS mytable_read ORDER BY last_used ASC LIMIT 1;        
        UPDATE mytable AS mytable_write SET last_used = unix_timestamp() WHERE unique_field_to_grab = @val LIMIT 1;
        UNLOCK TABLES;
        SELECT @val AS val;";

$result = $write->raw_fetchrow($sql, 'val');

Я также попытался использовать raw_query и query вместо raw_fetchrow без удачи.

Какие-либо мысли о том, почему это не работает? Или есть ли лучший способ выполнить это?

Править: Я начинаю думать, что это может быть связано с драйвером PDO, который определенно использует Magento. Я думаю, что phpMyAdmin использует mysqli, но я не могу подтвердить это.

1
задан Colin O'Dell 7 July 2010 в 19:42
поделиться

1 ответ

Возможно, функция, которую использует Magento, не поддерживает несколько sql-запросов. Вызывайте каждый оператор отдельно.

exec("LOCK TABLES mytable AS mytable_write WRITE, mytable AS mytable_read READ");
exec("SELECT @val := unique_field_to_grab FROM mytable AS mytable_read ORDER BY last_used ASC LIMIT 1");
exec("UPDATE mytable AS mytable_write SET last_used = unix_timestamp() WHERE unique_field_to_grab = @val LIMIT 1");
exec("UNLOCK TABLES");
exec("SELECT @val AS val");

Используйте соответствующие функции вместо exec().

2
ответ дан 2 September 2019 в 23:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: