使用导致问题的并行服务缓存表.唯一约束SQLException.Spring JDBC



使用oracle数据库。以下是我认为SQLException是如何发生的。。。

假设我有两个并行运行的服务实例。他们都做以下事情:

  1. 查询缓存(B)以查看Person是否存在
  2. 如果人员存在,但已过期或不存在=对主数据库进行查询(a)
  3. 如果在数据库(A)中找到人员,而之前在缓存(B)中未找到人员。INSERT,否则,如果之前在缓存中发现人员,但其UPDATE缓存已过期

我使用以下代码来做出决定,基于之前的查询来缓存B.

void insertOrUpdate(RegistryPersonMo person) {
    if (person.getId() == null) {
        insertPerson(person);
    } else {
        updatePerson(person);
    }
}

并使用Spring JDBC插入:

void insertPerson(RegistryPersonMo person) {
    Number id = insertInto("PERSON_REGISTRY", "RAAMAT").usingGeneratedKeyColumns("ID").executeAndReturnKey(usingParameters(person));
    if (id != null) {
        person.setId(id.longValue());
    }
}

当服务的两个实例已经完成了对缓存的查询(B),但没有找到人员(null)时,实际问题就会出现。然后一个实例执行INSERT,因为数据不存在。另一个在尝试执行相同操作时获得SQLException,因为具有唯一约束的条目已经存在。

有人知道最佳\标准解决方法是什么吗?我有一些想法:

  • 锁定行的读数,直到插入完成。我可以用Spring来做这件事吗
  • 使用replace或insert替换为ignore。仍在学习,这些有什么负面影响吗

请记住,我希望使用Spring并尽可能地自动化查询。。

我认为在这种情况下忽略唯一约束异常是可以的。是的,这是比赛条件,但达到了预期的一个期望的结果,插入了记录。也许记录它可以断言这种情况发生的频率。

锁定或事务序列化可以解决这个问题,但在我看来,在这种情况下没有多大意义。

最新更新