Mysql - Spring 引导 - 从代码执行存储过程与实际启动之间的未知延迟

Mysql - Spring Boot - Unknown delay between Stored procedure execution from code and actual start

我有一个 Spring 引导应用程序,其中 mysql 作为数据库。为了实现某些要求,我在 MySql 中实现了一个存储过程并通过我的 spring 启动代码触发它。

但是,我观察到的是,在我的 spring 启动代码被触发后,mysql 空闲了大约 90 秒。在该过程执行开始之后。这会减慢系统速度。如果这是预期的或者我做错了什么,有什么建议。

下面是我的 spring 调用过程的代码

@PersistenceContext
    private EntityManager entityManager;
@Transactional
    public void backFillClosingStock(String dbName, String id_list) throws Exception {
        try {
            ThreadLocalStorage.setTenantName(dbName);
            log.info("Starting backfilling closing stock");

            StoredProcedureQuery storedProcedure = entityManager.createStoredProcedureQuery("update_closing_stock");
            storedProcedure.registerStoredProcedureParameter("id_list", String.class, ParameterMode.IN);
            storedProcedure.setParameter("id_list", id_list );
            storedProcedure.execute();
            ThreadLocalStorage.setTenantName(null);
            log.info("Completed backfilling closing stock");
        } catch (Exception e) {
            throw new Exception("something went wrong!");

        }

下面是我的存储过程。

DELIMITER //
DROP PROCEDURE IF EXISTS update_closing_stock//
CREATE PROCEDURE update_closing_stock(id_list TEXT)
         BEGIN
            DECLARE done INT DEFAULT FALSE;
            DECLARE entryid1 decimal;
            DECLARE oldClosingStock decimal;
            DECLARE newClosingStock decimal;
            DECLARE isValueChanged INT DEFAULT 0; 
            DECLARE cur CURSOR FOR SELECT entryid FROM inward_outward_entries WHERE FIND_IN_SET(productId,id_list)>0 AND is_deleted=0;
            DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
            SET autocommit=0; 
            TRUNCATE temp;
            INSERT INTO temp VALUES (CONCAT('Procedure Started ',SYSDATE()));
            OPEN cur;
            ins_loop: LOOP
            FETCH cur INTO entryid1;
            IF done THEN
                LEAVE ins_loop;
            END IF;
            SELECT  
            bs1.closingStock as oldClosingStock,
            CASE WHEN bs1.type='Inward' THEN(
            (SELECT CASE WHEN SUM(bs2.quantity) IS NULL THEN 0 ELSE SUM(bs2.quantity) END FROM backfill_closing_stock bs2 
            WHERE bs2.id>=bs1.id AND bs2.type='Inward' AND bs1.Productid=bs2.productid AND bs2.warehouseid=bs1.warehouseid)
            -
            (SELECT CASE WHEN SUM(bs2.quantity)IS NULL THEN 0 ELSE SUM(bs2.quantity) END  FROM backfill_closing_stock bs2 
            WHERE bs2.id>bs1.id AND bs2.type!='Inward' AND bs1.Productid=bs2.productid AND bs2.warehouseid=bs1.warehouseid)
            )
            ELSE (
            (SELECT CASE WHEN SUM(bs2.quantity) IS NULL THEN 0 ELSE SUM(bs2.quantity) END  FROM backfill_closing_stock bs2 
            WHERE bs2.id>bs1.id AND bs2.type='Inward' AND bs1.Productid=bs2.productid AND bs2.warehouseid=bs1.warehouseid)
            -
            (SELECT CASE WHEN SUM(bs2.quantity) IS NULL THEN 0 ELSE SUM(bs2.quantity) END  FROM backfill_closing_stock bs2 
            WHERE bs2.id>=bs1.id AND bs2.type!='Inward' AND bs1.Productid=bs2.productid AND bs2.warehouseid=bs1.warehouseid)
            )
            END AS closingStock
            INTO oldClosingStock,newClosingStock
            FROM backfill_closing_stock bs1 WHERE bs1.entryid=entryid1;
           
             IF newClosingStock>=0 AND newClosingStock<>oldClosingStock THEN
                UPDATE inward_outward_entries SET closingStock = newClosingStock WHERE entryid=entryid1;
            END IF;
         END LOOP;
         CLOSE cur;
            TRUNCATE all_inventory_table;
            INSERT INTO all_inventory_table SELECT * FROM all_inventory;
        SET autocommit=1; 
END;

我在第 13 行和第 14 行分别有两个命令。用于截断 table 并向其中插入记录以进行调试。我可以看到 table 立即被截断,但仅在执行 90 秒后才将带有文本“Procedure Started”的记录插入到临时 table 中。不确定哪里出错了

以下是我的日志片段

2022-01-27 09:49:33,165 INFO  [Async-1] com.ec.application.service.AsyncServiceInventory: Before Procedure Start -2022-01-27T10:12:58.616

这表明程序是从 spring 在 10:12:58

触发的

但是当我检查临时 table 时,我没有看到在接下来的 90 秒内插入任何记录。在那之后,比如在 10:14:30,我看到一条记录被插入了过去的时间“程序开始于 2022-01-27 10:12:58'”

我不确定这 90 秒发生了什么。有什么建议吗?

TRUNCATE(和其他 DDL 语句)中断提交——至少在 MySQL 8.0

之前

autocommit=0 是 error-prone -- 如果您稍后忘记 COMMIT,可能会发生不好的事情。

所以,不要理会 autocommit 并结束 TRUNCATE。然后做

START TRANSACTION;
do all the rest of the work
COMMIT;

但是为了获得真正的性能提升,找到一种重写它的方法,这样您就不需要游标了。光标很慢。