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)