2012-03-29 2 views
1

Использование базы данных oracle. Вот как я думаю, что SQLException случается ...Таблицы кэша с параллельными службами, вызывающими проблемы. уникальное ограничение SQLException. Spring JDBC

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

  1. Query cache (B), чтобы узнать, существует ли там человек.
  2. Если человек существует, но устарел ИЛИ не существует = делает запрос в основной базе данных (A).
  3. Если лицо найдено в базе данных (A) и НЕ найдено ранее в кеше (B). INSERT, иначе, если человек ранее был найден в кеше, но был устаревшим кешем UPDATE.

Я использую следующий код, чтобы принять решение, основываясь на ранее запроса в кэш В.

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?
  • Используйте замену или вставку с игнорированием. все еще учусь, есть ли какие-то недостатки?

Имейте в виду, я хотел бы использовать Spring и автоматизировать запрос как можно больше ..

ответ

1

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

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

+0

Итак, вы предлагаете просто поймать исключение? – ollo

+0

Да. Лови и лог. В зависимости от вашего сценария использования вы почти никогда не видите, что это происходит на самом деле (если запрос для человека приходил случайным образом на один из серверов в любое время), или вы увидите, что это происходит много (когда запросы на одного и того же человека будут одновременно на оба сервера). Если это окажется проблемой, вы можете подумать, как ее решить. – maximdim

+0

Спасибо, сэр. – ollo