ОБНОВЛЕНИЕ MySQL и ВЫБОР в один проход - PullRequest
18 голосов
/ 18 февраля 2009

У меня есть таблица задач MySQL для выполнения, в каждой строке есть параметры для одной задачи.
Существует множество рабочих приложений (возможно, на разных компьютерах), выполняющих задачи в цикле.
Приложения получают доступ к базе данных с помощью собственных API-интерфейсов C MySQL.

Чтобы владеть задачей, приложение делает что-то вроде этого:

  • Создать глобально уникальный идентификатор (для простоты, скажем, это число)

  • UPDATE tasks
    SET guid = %d
    WHERE guid = 0 LIMIT 1

  • SELECT params
    FROM tasks
    WHERE guid = %d

  • Если последний запрос возвращает строку, мы владеем ею и имеем параметры для запуска

Есть ли способ достичь того же эффекта (то есть «владеть» строкой и получить ее параметры) за один вызов сервера?

Ответы [ 6 ]

9 голосов
/ 08 октября 2012

попробуй вот так

UPDATE `lastid` SET `idnum` =  (SELECT `id` FROM `history` ORDER BY `id` DESC LIMIT 1);

код выше работал для меня

6 голосов
/ 18 февраля 2009

Вы можете создать процедуру, которая делает это:

CREATE PROCEDURE prc_get_task (in_guid BINARY(16), OUT out_params VARCHAR(200))
BEGIN

  DECLARE task_id INT;

  SELECT id, out_params
  INTO task_id, out_params
  FROM tasks
  WHERE guid = 0
  LIMIT 1
  FOR UPDATE;

  UPDATE task
  SET guid = in_guid
  WHERE id = task_id;

END;

BEGIN TRANSACTION;

CALL prc_get_task(@guid, @params);

COMMIT;
1 голос
/ 20 ноября 2015

У меня точно такая же проблема. Вместо этого мы использовали PostreSQL, и UPDATE ... RETURNING:

Необязательное предложение RETURNING заставляет UPDATE вычислять и возвращать значения, основанные на каждой обновленной строке. Любое выражение, использующее столбцы таблицы и / или столбцы других таблиц, упомянутых в FROM, может быть вычислено. Новые (после обновления) значения столбцов таблицы используются. Синтаксис списка RETURNING идентичен синтаксису списка вывода SELECT.

Пример: UPDATE 'my_table' SET 'status' = 1 WHERE 'status' = 0 LIMIT 1 RETURNING *;

Или, в вашем случае: UPDATE 'tasks' SET 'guid' = %d WHERE 'guid' = 0 LIMIT 1 RETURNING 'params';

Извините, я знаю, что это не отвечает на вопрос с MySQL, и может быть нелегко просто переключиться на PostgreSQL, но мы нашли лучший способ сделать это. Даже 6 лет спустя MySQL по-прежнему не поддерживает UPDATE ... RETURNING. Он может быть добавлен в какой-то момент в будущем, но пока MariaDB имеет его только для операторов DELETE .

Редактировать : существует задача (низкий приоритет) для добавления UPDATE ... RETURNING поддержки MariaDB .

1 голос
/ 19 февраля 2009

Если вы ищете один запрос, то это не может произойти. Функция UPDATE, в частности, возвращает только количество элементов, которые были обновлены. Точно так же функция SELECT не изменяет таблицу, а только возвращает значения.

Использование процедуры действительно превратит ее в одну функцию, и это может быть удобно, если для вас важна блокировка. Если вас больше всего беспокоит сетевой трафик (т. Е. Передача слишком большого количества запросов), воспользуйтесь процедурой. Если вас беспокоит перегрузка сервера (то есть: БД работает слишком усердно), то дополнительные издержки процедуры могут ухудшить ситуацию.

0 голосов
/ 07 августа 2014
UPDATE tasks
SET guid = %d, params = @params := params
WHERE guid = 0 LIMIT 1;

Возвращается 1 или 0, в зависимости от того, были ли значения эффективно изменены.

SELECT @params AS params;

Этот просто выбирает переменную из соединения.

От: здесь

0 голосов
/ 18 февраля 2009

Я не знаю насчет части одного вызова, но то, что вы описываете, - это блокировка. Блокировки являются важным элементом реляционных баз данных.

Я не знаю специфики блокировки строки, ее чтения и последующего обновления в MySQL, но с небольшим чтением документации блокировки mysql вы могли бы делать все виды блокировок. основанные манипуляции.

Документация postgres lock содержит отличный пример, описывающий, что именно вы хотите сделать: заблокировать таблицу, прочитать таблицу, изменить таблицу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...