Триггер UPDATE приводит к тупику - Mysql 5.6 - PullRequest
0 голосов
/ 23 сентября 2019

Mysql версия: 5.6

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

DROP TRIGGER IF EXISTS pieces_after_update;

CREATE TRIGGER pieces_after_update
AFTER UPDATE
   ON pieces FOR EACH ROW
BEGIN
    SET @COMPANYID = (SELECT company_id FROM skus where id = NEW.sku_id);
    SET @CLOSINGSTOCK = (SELECT closing_stock FROM skus_warehouses WHERE sku_id=NEW.sku_id AND warehouse_id=NEW.warehouse_id ORDER BY ID DESC LIMIT 1);
    SET @CLOSINGPENDINGSTOCK = (SELECT closing_pending_stock FROM skus_warehouses WHERE sku_id=NEW.sku_id AND warehouse_id=NEW.warehouse_id ORDER BY ID DESC LIMIT 1);
    IF (@CLOSINGSTOCK IS NULL)
    THEN
        SET @CLOSINGSTOCK=0;
    END IF;

    ##movement from putaway_pending to putaway_done for good stock
    IF (NEW.stock_status_id=4 AND NEW.is_bad_stock=0 AND OLD.stock_status_id=3) 
    THEN        
        INSERT INTO skus_warehouses(sku_id, warehouse_id, company_id, comment, stock_changed_by, closing_stock, closing_pending_stock)
        VALUES(NEW.sku_id, NEW.warehouse_id, @COMPANYID, CONCAT_WS(' - ','Stock Added by putaway of serial no ', NEW.id), 1, @CLOSINGSTOCK+1, @CLOSINGPENDINGSTOCK); 
    END IF; 

    ##movement from putaway_done to blocked for an order/outward entity
    IF(NEW.stock_status_id=5  AND NEW.is_bad_stock=0 AND OLD.stock_status_id=4)
    THEN
        INSERT INTO skus_warehouses(sku_id, warehouse_id, company_id, comment, stock_changed_by, closing_stock, closing_pending_stock)
        VALUES(NEW.sku_id, NEW.warehouse_id, @COMPANYID, CONCAT_WS(' - ','Stock blocked for serial no ', NEW.id, ' for ', NEW.outward_entity_type, ' id ', NEW.outward_entity_id), -1, @CLOSINGSTOCK-1, @CLOSINGPENDINGSTOCK); 
    END  IF;

    ##movement from BLOCKED to PUTAWAY_DONE for an order/outward entity. Unblocking case, needs adjustment entry in SkuW
    IF(NEW.stock_status_id=4  AND OLD.stock_status_id=5 AND NEW.is_bad_stock=0)
    THEN        
        INSERT INTO skus_warehouses(sku_id, warehouse_id, company_id, comment, stock_changed_by, closing_stock, closing_pending_stock)
        VALUES(NEW.sku_id, NEW.warehouse_id, @COMPANYID, CONCAT_WS(' - ','Stock UNblocked for serial no ', NEW.id, ' for ', NEW.outward_entity_type, ' id ', NEW.outward_entity_id), 1, @CLOSINGSTOCK+1, @CLOSINGPENDINGSTOCK); 
    END  IF;  

    ##movement from PUTAWAY_DONE to PICKED (missed BLOCKED) for an order/outward entity
    IF(NEW.stock_status_id=6  AND NEW.is_bad_stock=0 AND OLD.stock_status_id=4)
    THEN
        INSERT INTO skus_warehouses(sku_id, warehouse_id, company_id, comment, stock_changed_by, closing_stock, closing_pending_stock)
        VALUES(NEW.sku_id, NEW.warehouse_id, @COMPANYID, CONCAT_WS(' - ','Stock blocked & picked for serial no ', NEW.id, ' for ', NEW.outward_entity_type, ' id ', NEW.outward_entity_id), -1, @CLOSINGSTOCK-1, @CLOSINGPENDINGSTOCK); 
    END  IF;

    ##movement from PICKED to PUTAWAY_DONE for an order/outward entity. Unpicking case, needs adjustment entry in SkuW
    IF(NEW.stock_status_id=4  AND OLD.stock_status_id=6 AND NEW.is_bad_stock=0)
    THEN        
        INSERT INTO skus_warehouses(sku_id, warehouse_id, company_id, comment, stock_changed_by, closing_stock, closing_pending_stock)
        VALUES(NEW.sku_id, NEW.warehouse_id, @COMPANYID, CONCAT_WS(' - ','Stock Unpicked & Unblocked for serial no ', NEW.id, ' for ', OLD.outward_entity_type, ' id ', OLD.outward_entity_id), 1, @CLOSINGSTOCK+1, @CLOSINGPENDINGSTOCK); 
    END  IF; 

    ##movement from PUTAWAY_DONE/good_stock to PUTAWAY_PENDING/bad_stock
    IF(NEW.is_bad_stock=1 AND OLD.stock_status_id=4 AND NEW.stock_status_id=3)
    THEN
        INSERT INTO skus_warehouses(sku_id, warehouse_id, company_id, comment, stock_changed_by, closing_stock, closing_pending_stock)
        VALUES(NEW.sku_id, NEW.warehouse_id, @COMPANYID, CONCAT_WS(' - ','Stock marked as BADSTOCK for serial no ', NEW.id), -1,@CLOSINGSTOCK-1, @CLOSINGPENDINGSTOCK);
    END IF;

    ##movement from PUTAWAY_DONE to INVALIDATED
    IF(OLD.stock_status_id=4 AND NEW.stock_status_id=10)
    THEN
        INSERT INTO skus_warehouses(sku_id, warehouse_id, company_id, comment, stock_changed_by, closing_stock, closing_pending_stock)
        VALUES(NEW.sku_id, NEW.warehouse_id, @COMPANYID, CONCAT_WS(' - ','Invalidated serial no ', NEW.id), -1,@CLOSINGSTOCK-1, @CLOSINGPENDINGSTOCK);
    END IF;

END; //

Я знаю, что получаю взаимоблокировки для триггера, потому что это то, что я нашел в SHOW INNODB ENGINE STATUS

*** (1) TRANSACTION:
TRANSACTION 635520869854, ACTIVE 0 sec fetching rows
mysql tables in use 5, locked 3
LOCK WAIT 1625 lock struct(s), heap size 177704, 7983 row lock(s), undo log entries 1
MySQL thread id 2085967891, OS thread handle 0x2b5e2d4d1700, query id 503500721288 10.0.10.59 primary_db_user Creating sort index
SET @CLOSINGSTOCK = (SELECT closing_stock FROM skus_warehouses WHERE sku_id=NEW.sku_id AND warehouse_id=NEW.warehouse_id ORDER BY ID DESC LIMIT 1)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 139169 page no 7248658 n bits 216 index `PRIMARY` of table `primary_db`.`skus_warehouses` trx id 635520869854 lock_mode X locks rec but not gap waiting
Record lock, heap no 121 PHYSICAL RECORD: n_fields 14; compact format; info bits 0

Таблица skus_warehouses имеет 100M +записи, но имеет хорошую индексацию.Все нижеуказанные запросы (которые кажутся взаимоблокировочными) завершаются за 0,5 с 1 с.

SET @CLOSINGSTOCK = (SELECT closing_stock FROM skus_warehouses WHERE sku_id=NEW.sku_id AND warehouse_id=NEW.warehouse_id ORDER BY ID DESC LIMIT 1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...