Spring Boot jOOQ的batchInsert()在“after insert”触发器中的行为不符合预期

cgvd09ve  于 2023-06-22  发布在  Spring
关注(0)|答案(1)|浏览(140)

说明

我有一个触发器,它在插入sku表后插入sku_price_history表:

DELIMITER $$
CREATE TRIGGER trig_after_sku_insert
    AFTER INSERT
ON sku FOR EACH ROW
BEGIN
    INSERT INTO sku_price_history(sku_id, action_type, purchase_price, selling_price, base_margin_rate,
                                  vat, vat_type, tax_type, selling_price_started_at, updated_by)
    VALUES (NEW.id, 'CREATE', NEW.purchase_price, NEW.selling_price, NEW.base_margin_rate,
            NEW.vat, NEW.vat_type, NEW.tax_type, NOW(), NEW.created_by);
END $$
DELIMITER ;

然后,我尝试使用jOOQ的DSLContext.batchInsert()执行一个简单的批处理插入:

void saveMany(List<SkuDto.SaveBody> skus) {
    List<SkuRecord> skuRecords = new ArrayList<>();
    for(SkuDto.SaveBody sku : skus) {
        SkuRecord skuRecord = ctx.newRecord(SKU, sku);
        skuRecords.add(skuRecord);
    }
    ctx.batchInsert(skuRecords).execute();
}

问题

上面的语句只将第一行插入到sku表中,即使有很多记录。根据LoggerListener,没有抛出异常,并且批处理大小是正确的:

DEBUG 65174 --- [nio-9292-exec-1] org.jooq.tools.LoggerListener : Executing batch query : sql query
DEBUG 65174 --- [nio-9292-exec-1] org.jooq.tools.LoggerListener : Batch size            : 3

我所尝试的

1.我在放下触发器后执行了相同的代码,它工作了。所以触发器似乎是这里的主要原因。
1.然后,我尝试使用SQL客户端模拟这个问题,在事务中运行多个insert语句:

SET autocommit = OFF;
START TRANSACTION;
INSERT INTO sku (fields) VALUES (values);
INSERT INTO sku (fields) VALUES (values);
INSERT INTO sku (fields) VALUES (values);
COMMIT;

上述SQL语句按预期工作,记录被插入到skusku_price_history表中。
我可能遗漏了一些关于触发器和批处理插入的要点,但我找不到相关信息。我正在使用Sping Boot 默认配置。

版本号:
  • jOOQ:3.18.2
  • java :17人
  • Sping Boot :3.0.5
  • 数据库(包括供应商):MariaDB 10.6(RDS)
rta7y2nd

rta7y2nd1#

经过Lukas Eder的有益指导,我发现我遇到的问题不是jOOQ本身的bug,而是MariaDB JDBC driver的bug。我记录了在询问jOOQ相关问题之前要采取的步骤,以便于公众了解。它可以帮助其他人(或我自己)谁遇到类似的问题在未来。
1.当您认为jOOQ没有按预期工作时,检查副作用。副作用可以是从应用程序级VisitListener到数据库级触发器的任何东西。我花了几个小时试图解决这个问题,直到我发现这是因为一个触发器。
1.直接使用JDBC再现问题。如果同样的问题发生,那么很可能不是jOOQ的问题
1.最好使用官方驱动程序,但为了识别问题,请尝试切换JDBC驱动程序,如果可以的话。例如,从MariaDB Connector/J到MySQL Connector/J。
我按照上面的步骤操作,在从MariaDB Connector/J切换到MySQL Connector/J后解决了这个问题。这证实了问题不在于jOOQ本身,而在于我使用的特定MariaDB JDBC驱动程序。我想我可以继续使用MySQL驱动程序,因为根据文档,它与JDBC 4.2规范兼容。
MySQL Connector/J 8.0是JDBC Type 4驱动程序,与JDBC 4.2规范兼容。

相关问题