首页 > 解决方案 > 执行 INSERT 的 SQL 错误:[SQLITE_BUSY] 数据库文件被锁定

问题描述

我在我的 Micronaut 应用程序中使用 sqlite 作为 db,在以下代码中出现 sqlite busy 错误:

    @SneakyThrows
    @TransactionalAdvice(value = EmpDao.DATASOURCE, propagation = TransactionDefinition.Propagation.REQUIRES_NEW)
    public void storeEmp(EmpDto empDto) {
        String id = empDto.getId();
        try {
            if (empDao.existsById(id)) {
                log.debug("updating emp for id {}", empDto.getId());
                empDao.update(EmpEntity.builder()
                        .id(id)
                        .data(getJson(empDto))
                        .entryCreatedAt(timeService.nowDateTime().toEpochSecond(ZoneOffset.UTC))
                        .build());
            } else {
                empDao.save(
                           EmpEntity.builder()
                        .id(id)
                        .data(getJson(empDto))
                        .entryCreatedAt(timeService.nowDateTime().toEpochSecond(ZoneOffset.UTC))
                        .build());
            }
        }catch(Exception e){
            log.error("emp db save/update failed for id {} ",id, e);
        }
    }

    @SneakyThrows
    @TransactionalAdvice(value = EmpDao.DATASOURCE, propagation = TransactionDefinition.Propagation.REQUIRES_NEW)
    public void storeEmployees(List<Emp> empDtos) {
        try {
            empDao.saveAll(empDto);
        } catch (Exception ex) {
            log.warn("saveAll failed", ex);
            empDtos.forEach(this::storeEmp);
        }
    }

在堆栈跟踪中,我可以看到saveAll由于主键约束问题而首先失败,这可能是由于列表中重复的 emp id

SQL error executing INSERT: [SQLITE_CONSTRAINT_PRIMARYKEY]  A PRIMARY KEY constraint failed

之后,当它尝试通过 forEach 中的 storeEmp 方法独立保存/更新每个 emp 对象时,它因 sqlite busy 异常而失败。

我不确定 saveAll 是否已经失败,如何与 sqlite 建立多个连接。任何人都可以建议上面的代码有什么问题。

谢谢

标签: sqliteconnectionprimary-keyunique-constraintmicronaut

解决方案


推荐阅读