MySQL Triggers - 5.7.23-0ubuntu0.16.04.1 - странное поведение не каждый раз работает - PullRequest
0 голосов
/ 10 октября 2018

Я разработал приложение на Python 3, используя среду торнадо, которая подключается к огромной базе данных MySQL, содержащей миллионы строк.

Эта база данных синхронизируется в режиме реального времени, поэтому данные вставляются и удаляются, а затемобновлено, поэтому было создано 3 триггера: вставка, обновление и удаление.

Но триггеры ведут себя очень странно, иногда они работают, а иногда не работают, например, когда они решают, что получают данные и делают то, что должныда, в другой раз они просто игнорируют это.

Версия MySQL - это 5.7.23-0ubuntu0.16.04.1

Также я вставил 3 триггера, которыев моей базе данных может быть логическая ошибка в моих триггерах:

INSERT

BEGIN
  IF (SELECT count(*) FROM USERS_STATS WHERE LOGIN = NEW.LOGIN) = 0 THEN
    INSERT INTO USERS_STATS (LOGIN) values (NEW.LOGIN);
  END IF;
  UPDATE USERS_STATS SET
    TOTAL_DEPOSIT = TOTAL_DEPOSIT + IF(NEW.CMD = 6 AND NEW.COMMENT NOT LIKE '%internal%' AND NEW.COMMENT NOT LIKE '%Tr %' AND NEW.COMMENT NOT LIKE '%agent%' AND NEW.COMMENT NOT LIKE '%rebate%' AND NEW.COMMENT NOT LIKE '%MAM:CASH%' AND NEW.PROFIT > 0, NEW.PROFIT, 0),
    TOTAL_WITHDRAW = TOTAL_WITHDRAW + IF(NEW.CMD = 6 AND NEW.COMMENT NOT LIKE '%internal%' AND NEW.COMMENT NOT LIKE '%Tr %' AND NEW.COMMENT NOT LIKE '%agent%' AND NEW.COMMENT NOT LIKE '%rebate%' AND NEW.COMMENT NOT LIKE '%MAM:CASH%' AND NEW.PROFIT < 0, NEW.PROFIT, 0),
    TOTAL_VOLUME = TOTAL_VOLUME + IF(NEW.CMD IN(0, 1) AND NEW.CLOSE_TIME > '1970-01-01', NEW.VOLUME, 0),
    TOTAL_REBATE = TOTAL_REBATE + IF((NEW.COMMENT LIKE '%agent%' OR NEW.COMMENT LIKE '%rebate%' OR NEW.COMMENT LIKE '%MAM:CASH%'), ROUND(NEW.PROFIT, 2), 0)
  WHERE LOGIN = NEW.LOGIN;
END

ОБНОВЛЕНИЕ

BEGIN
  DECLARE old_is_deposit integer;
  DECLARE new_is_deposit integer;
  DECLARE old_is_withdraw integer;
  DECLARE new_is_withdraw integer;
  DECLARE old_is_rebate integer;
  DECLARE new_is_rebate integer;
  SET old_is_deposit := OLD.CMD = 6 AND OLD.COMMENT NOT LIKE '%internal%' AND OLD.COMMENT NOT LIKE '%Tr %' AND OLD.COMMENT NOT LIKE '%agent%' AND OLD.COMMENT NOT LIKE '%rebate%' AND OLD.COMMENT NOT LIKE '%MAM:CASH%' AND OLD.PROFIT > 0;
  SET new_is_deposit := NEW.CMD = 6 AND NEW.COMMENT NOT LIKE '%internal%' AND NEW.COMMENT NOT LIKE '%Tr %' AND NEW.COMMENT NOT LIKE '%agent%' AND NEW.COMMENT NOT LIKE '%rebate%' AND NEW.COMMENT NOT LIKE '%MAM:CASH%' AND NEW.PROFIT > 0;
  SET old_is_withdraw := OLD.CMD = 6 AND OLD.COMMENT NOT LIKE '%internal%' AND OLD.COMMENT NOT LIKE '%Tr %' AND OLD.COMMENT NOT LIKE '%agent%' AND OLD.COMMENT NOT LIKE '%rebate%' AND OLD.COMMENT NOT LIKE '%MAM:CASH%' AND OLD.PROFIT < 0;
  SET new_is_withdraw := NEW.CMD = 6 AND NEW.COMMENT NOT LIKE '%internal%' AND NEW.COMMENT NOT LIKE '%Tr %' AND NEW.COMMENT NOT LIKE '%agent%' AND NEW.COMMENT NOT LIKE '%rebate%' AND NEW.COMMENT NOT LIKE '%MAM:CASH%' AND NEW.PROFIT < 0;
  SET old_is_rebate := OLD.COMMENT LIKE '%agent%' OR OLD.COMMENT LIKE '%rebate%' OR OLD.COMMENT LIKE '%MAM:CASH%';
  SET new_is_rebate := NEW.COMMENT LIKE '%agent%' OR NEW.COMMENT LIKE '%rebate%' OR NEW.COMMENT LIKE '%MAM:CASH%';
  IF (SELECT count(*) FROM USERS_STATS WHERE LOGIN = NEW.LOGIN) = 0 THEN
    INSERT INTO USERS_STATS (LOGIN) values (NEW.LOGIN);
  END IF;
  IF (old_is_deposit = 1 AND new_is_deposit = 1 AND OLD.PROFIT != NEW.PROFIT) THEN
    UPDATE USERS_STATS SET
      TOTAL_DEPOSIT = TOTAL_DEPOSIT + (NEW.PROFIT - OLD.PROFIT)
    WHERE LOGIN = OLD.LOGIN;
  ELSEIF (old_is_withdraw = 1 AND new_is_withdraw = 1 AND OLD.PROFIT != NEW.PROFIT) THEN
    UPDATE USERS_STATS SET
      TOTAL_WITHDRAW = TOTAL_WITHDRAW + (NEW.PROFIT - OLD.PROFIT)
    WHERE LOGIN = OLD.LOGIN;
  ELSEIF (old_is_deposit = 1 AND new_is_withdraw = 1) THEN
    UPDATE USERS_STATS SET
      TOTAL_DEPOSIT = TOTAL_DEPOSIT - OLD.PROFIT,
      TOTAL_WITHDRAW = TOTAL_WITHDRAW + NEW.PROFIT
    WHERE LOGIN = OLD.LOGIN;
  ELSEIF (old_is_withdraw = 1 AND new_is_deposit = 1) THEN
    UPDATE USERS_STATS SET
      TOTAL_DEPOSIT = TOTAL_DEPOSIT + NEW.PROFIT,
      TOTAL_WITHDRAW = TOTAL_WITHDRAW - OLD.PROFIT
    WHERE LOGIN = OLD.LOGIN;
  ELSEIF (old_is_deposit = 0 AND new_is_deposit = 1) THEN
    UPDATE USERS_STATS SET
      TOTAL_DEPOSIT = TOTAL_DEPOSIT + NEW.PROFIT
    WHERE LOGIN = OLD.LOGIN;
  ELSEIF (old_is_deposit = 1 AND new_is_deposit = 0) THEN
    UPDATE USERS_STATS SET
      TOTAL_DEPOSIT = TOTAL_DEPOSIT - OLD.PROFIT
    WHERE LOGIN = OLD.LOGIN;
  ELSEIF (old_is_withdraw = 0 AND new_is_withdraw = 1) THEN
    UPDATE USERS_STATS SET
      TOTAL_WITHDRAW = TOTAL_WITHDRAW + NEW.PROFIT
    WHERE LOGIN = OLD.LOGIN;
  ELSEIF (old_is_withdraw = 1 AND new_is_withdraw = 0) THEN
    UPDATE USERS_STATS SET
      TOTAL_WITHDRAW = TOTAL_WITHDRAW - OLD.PROFIT
    WHERE LOGIN = OLD.LOGIN;
  END IF;
  IF (OLD.VOLUME != NEW.VOLUME) THEN
    UPDATE USERS_STATS SET
      TOTAL_VOLUME = TOTAL_VOLUME + (NEW.VOLUME - OLD.VOLUME)
    WHERE LOGIN = OLD.LOGIN;
  END IF;
  IF (old_is_rebate = 1 AND new_is_rebate = 1 AND OLD.PROFIT != NEW.PROFIT) THEN
    UPDATE USERS_STATS SET
      TOTAL_REBATE = TOTAL_REBATE + (ROUND(NEW.PROFIT, 2) - ROUND(OLD.PROFIT, 2))
    WHERE LOGIN = OLD.LOGIN;
  ELSEIF (old_is_rebate = 0 AND new_is_rebate = 1) THEN
    UPDATE USERS_STATS SET
      TOTAL_REBATE = TOTAL_REBATE + ROUND(NEW.PROFIT, 2)
    WHERE LOGIN = OLD.LOGIN;
  ELSEIF (old_is_rebate = 1 AND new_is_rebate = 0) THEN
    UPDATE USERS_STATS SET
      TOTAL_REBATE = TOTAL_REBATE - ROUND(OLD.PROFIT, 2)
    WHERE LOGIN = OLD.LOGIN;
  END IF;
END

УДАЛИТЬ

BEGIN
  IF (SELECT count(*) FROM USERS_STATS WHERE LOGIN = OLD.LOGIN) = 0 THEN
    INSERT INTO USERS_STATS (LOGIN) values (OLD.LOGIN);
  END IF;
  UPDATE USERS_STATS SET
    TOTAL_DEPOSIT = TOTAL_DEPOSIT - IF(OLD.CMD = 6 AND OLD.COMMENT NOT LIKE '%internal%' AND OLD.COMMENT NOT LIKE '%Tr %' AND OLD.COMMENT NOT LIKE '%agent%' AND OLD.COMMENT NOT LIKE '%rebate%' AND OLD.COMMENT NOT LIKE '%MAM:CASH%' AND OLD.PROFIT > 0, OLD.PROFIT, 0),
    TOTAL_WITHDRAW = TOTAL_WITHDRAW - IF(OLD.CMD = 6 AND OLD.COMMENT NOT LIKE '%internal%' AND OLD.COMMENT NOT LIKE '%Tr %' AND OLD.COMMENT NOT LIKE '%agent%' AND OLD.COMMENT NOT LIKE '%rebate%' AND OLD.COMMENT NOT LIKE '%MAM:CASH%' AND OLD.PROFIT < 0, OLD.PROFIT, 0),
    TOTAL_VOLUME = TOTAL_VOLUME - IF(OLD.CMD IN(0, 1) AND OLD.CLOSE_TIME > '1970-01-01', OLD.VOLUME, 0),
    TOTAL_REBATE = TOTAL_REBATE - IF((OLD.COMMENT LIKE '%agent%' OR OLD.COMMENT LIKE '%rebate%' OR OLD.COMMENT LIKE '%MAM:CASH%'), ROUND(OLD.PROFIT, 2), 0)
  WHERE LOGIN = OLD.LOGIN;
END

Также я прикрепил скриншот, как устроены триггеры: enter image description here

Нужна помощь, почему мои триггеры неработает правильно.Заранее благодарю.

1 Ответ

0 голосов
/ 11 октября 2018

Итак, в конце концов я нашел другую логику, которая не могла выйти из тупика в моем случае, поэтому вместо вышеупомянутых триггеров с помощью скрипта cronjob я смог обновить все необходимые данные за один интервал времени, который выполнялись триггерами.

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