Обработка нарушений целостности Java + MySQL - PullRequest
4 голосов
/ 04 февраля 2010

Я пишу программу на Java, используя JDBC (база данных mysql). Когда я нарушаю целостность mysql (например, я пытаюсь вставить то же значение первичного ключа), я ловлю исключение SQL. Должен ли я писать так, чтобы этого никогда не происходило (например, при первой булевой функции, проверяющей, нет ли значения первичного ключа, еще нет в БД, а затем вызывающей вставку), или можно обрабатывать это только по исключению? Пример:

catch (SQLException ex) {ex.printStackTrace(); showSomeErrorDialog(); }

Ответы [ 3 ]

4 голосов
/ 04 февраля 2010

В сущности, есть два способа добиться этого:

  1. Проверьте, существует ли запись перед вставкой - в ту же транзакцию.

  2. Определите, начинается ли SQLException#getSQLState() перехваченного SQLException с 23, что является нарушением ограничения согласно спецификации SQL . Именно это может быть вызвано большим количеством факторов, чем просто нарушение ограничения. Вы не должны исправлять каждый SQLException как нарушение ограничения.

    public static boolean isConstraintViolation(SQLException e) {
        return e.getSQLState().startsWith("23");
    }
    

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

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

2 голосов
/ 04 февраля 2010

Есть два возможных ответа:

  • если вы знаете, что ваше приложение разработано таким образом, чтобы избежать такого поведения, используйте исключение
  • если ваше приложение может часто делать эти ошибки, используйте тест.
1 голос
/ 02 февраля 2016

Как уже упоминалось, есть два возможных подхода, один из которых - протестировать, а затем вставить / обновить, иначе обработать исключение SQL. Оба этих подхода имеют свои недостатки:

  • Предостережение для "Тест перед вставкой" заключается в том, что каждый транзакция будет иметь дополнительные запросы, которые будут влиять на производительность. Это особенно большая проблема, когда таких ошибочных транзакций мало.
  • Предостережение для "оценки исключения SQL" заключается в том, что такое Сообщения об исключениях очень специфичны для базы данных. Эти сообщения, в большинстве случаев, не предоставить конкретную информацию, не указав, что имеет место нарушение ограничений.

Итак, я предложу подход, который является гибридом двух .

  • Не выполнять тест перед вставкой.
  • Позвольте базе данных бросить исключение.
  • Catch SQL Exception.
  • В потоке исключений (catch блок), выполните дополнительные запросы, чтобы сформировать очень конкретные сообщения об ошибках для указать клиентам, что именно не удалось (уникальный ключ, первичный ключ, внешний ключ, определенные столбцы и т. д.).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...