Кэшировать таблицы с параллельными сервисами, вызывающими проблемы.уникальное ограничение SQLException.Spring JDBC - PullRequest
1 голос
/ 29 марта 2012

Использование базы данных Oracle. Вот как я думаю, что SQLException происходит ...

Скажем, у меня есть два экземпляра службы, работающей параллельно. Они оба делают следующее:

  1. Запрос кеша (B), чтобы увидеть, существует ли там человек.
  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), а человек не был найден (пусто). Затем один экземпляр выполняет INSERT, потому что данные не существуют. Другой получает SQLException при попытке сделать то же самое, поскольку запись с уникальным ограничением уже существует.

Кто-нибудь знает, что такое лучший \ стандартный обходной путь ? Некоторые идеи, которые у меня были:

  • Блокировка чтения строки до завершения вставки. Могу ли я сделать это с помощью Spring?
  • Используйте заменить или вставить с игнорированием. все еще учусь, есть ли минусы к ним?

Помните, что я хотел бы использовать Spring и максимально автоматизировать запрос ..

1 Ответ

1 голос
/ 29 марта 2012

Я думаю, что в этой ситуации нормально просто игнорировать исключение уникального ограничения.Да, это состояние гонки, но ожидаемый результат - желаемый результат достигнут, запись вставлена.Возможно, войдите в него, чтобы иметь возможность утверждать, как часто это происходит.

Блокировка или сериализация транзакций решит эту проблему, но, на мой взгляд, не будет иметь особого смысла в этом случае.

...