说明
我有一个触发器,它在插入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语句按预期工作,记录被插入到sku
和sku_price_history
表中。
我可能遗漏了一些关于触发器和批处理插入的要点,但我找不到相关信息。我正在使用Sping Boot 默认配置。
版本号:
- jOOQ:3.18.2
- java :17人
- Sping Boot :3.0.5
- 数据库(包括供应商):MariaDB 10.6(RDS)
1条答案
按热度按时间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规范兼容。