Должен ли я проверять ограничения БД в коде или я должен улавливать исключения, выданные БД
У меня есть приложение, которое сохраняет данные в таблицу с именем Джобс. В таблице Jobs есть столбец с именем Name, у которого есть ограничение UNIQUE. Столбец Name не является PRIMARY KEY. Интересно, нужно ли мне проверять дубликаты записей, прежде чем пытаться сохранить/обновить новую запись или лучше подождать исключения, созданного уровнем доступа к данным. Я использую NHibernate для этого приложения, если он имеет значение
Спасибо всем за большой вклад.
Я нашел еще одну причину, по которой я должен проверять код, а не просто ждать, когда будет выбрано исключение (и поймано моим кодом). Кажется, что NHibernate будет генерировать только NHibernate.Exceptions.GenericADOException, который не очень информативен относительно причины исключения в этом случае. Или я пропустил аспект NHibernate здесь?
Ответы
Ответ 1
Ответ: оба.
Если ваша база данных имеет ограничения, она может гарантировать определенные инварианты относительно данных, таких как уникальность. Это помогает несколькими способами:
-
Если у вас есть ошибка в вашем
применения, нарушая
ограничение будет отмечать что-то, что
в противном случае не может быть замечено.
-
Другие пользователи базы данных могут
больше полагаться на поведение
данные, используемые СУБД
инварианты.
-
База данных защищает себя от
неправильные обновления, которые нарушают
ограничения. Если вы обнаружите, что у вас есть другие
системы или интерфейса, заполняющих
базы данных по дорожке,
ограничения, установленные базой данных
означает, что все, что
ограничения не будут (или, по крайней мере,
менее вероятно) нарушит вашу систему.
Приложения и базы данных живут в отношениях M: M в любых, но самых тривиальных случаях. В приложении все еще должны быть правильные проверки данных и бизнес-правил, но вы все равно не должны планировать, что ваше приложение является единственным клиентом данных. Работайте в хранилище данных в течение нескольких лет, и вы увидите эффекты приложений, разработанных людьми с этим мышлением.
Ответ 2
Если ваш проект хорош (как база данных, так и BL), база данных не должна иметь никаких ограничений, которые не будут обрабатываться в BL - то есть вы не должны представлять базу данных с непоследовательными данными. Но ничто не идеально.
Я обнаружил, что ограничение базы данных для ограничений согласованности данных позволяет мне обрабатывать всю проверку BL в процедурном коде, и единственными случаями, когда я испытываю исключения базы данных, являются ошибки проектирования и кодирования, которые могут (и должны быть) исправлены.
В вашем случае проверка имени уникальности - это проверка содержимого данных, правильная обработка кода. Что, вероятно, улавливает ошибку, ближайшую к точке комиссии, где, как мы надеемся, есть более дружественные ресурсы пользовательского интерфейса для вызова без введения нежелательной связи между абстракциями.
Ответ 3
Я полностью оставил бы эту работу в базе данных; ваш код должен сосредоточиться на ловушке и правильном обращении с этим исключением.
Причины:
- Производительность. База данных будет
высоко оптимизирована для обеспечения соблюдения
ограничения в быстром и эффективном
путь. У вас не будет времени на
оптимизируйте свой код.
- Поддержание работоспособности. Если ограничения
изменения в будущем, у вас не будет
изменить свой код, или, возможно, вы
просто нужно добавить новый catch {}.
Если ограничение отключено, вы
не придется прикасаться к вашему коду
все.
Ответ 4
Если вы сами проверите ограничения, сделайте это на уровне доступа к данным. Ничто выше этого уровня не должно знать ничего о вашей базе данных или ее ограничениях.
В большинстве случаев я бы сказал, чтобы он оставил DAL, чтобы поймать исключения из БД. Но в вашем конкретном случае, я думаю, мы говорим об основной проверке ввода. Я бы выбрал вызов проверки доступности имени в базе данных, прежде чем отправлять всю форму.
Ответ 5
Вы должны обязательно проверить, нет ли каких-либо исключений, создаваемых уровнем доступа к данным. Проблема с проверкой наличия записи с тем же значением заключается в том, что она требует, чтобы вы заблокировали таблицу для модификации, пока не введете новую запись, чтобы предотвратить условия гонки.
Обычно рекомендуется проверять исключения/ошибки, даже если вы сами все проверили сами. Существует почти всегда что-то, что может пойти не так, или которое вы не учли в своем коде, но принудительно используется базой данных.
Изменить: Если я правильно понимаю вопрос, речь идет не о том, следует ли принудительно применять ограничение в базе данных или нет, но как бороться с ним в коде приложения. Конечно, вы должны всегда настраивать все ограничения в базе данных, чтобы предотвратить попадание плохих данных в вашу базу данных.
Ответ 6
Вопрос, на который вы должны ответить:
"Мне нужно представить пользователю приятные сообщения". Пример. Уже есть Job с именем TestJob1.
Если ответ Нет, просто поймайте ошибку и представите общее сообщение
Если ответ Да, продолжайте читать
Если вы поймаете ошибку после вставки, недостаточно информации, чтобы представить правильное сообщение (по крайней мере, по агностическому пути БД)
С другой стороны, могут быть условия гонки, и вы можете иметь одновременную транзакцию, пытающуюся вставить те же данные, поэтому вам нужно ограничение DB
Хороший подход:
- проверить перед тем, как подарить хороший
сообщение
- поймать исключение и
представить общее сообщение об ошибке
(при условии, что этого не произойдет очень
часто)
Ответ 7
Лично я поймаю исключение. Это намного проще и требует гораздо меньше кода.
Ответ 8
Внутреннее исключение GenericADOException скажет вам, почему действие базы данных не удалось. Вы можете поймать OracleException/MSSQLException/[InsertCustomExceptionHere] и обработать ошибку из этого сообщения. Если вы хотите передать это обратно на передний план (при условии, что пользователь является тем, кто ввел повторяющиеся данные), вы можете сначала его обернуть в пользовательское исключение, чтобы вы не привязывали свой интерфейс к базе данных. Вы действительно не хотите передавать определенные исключения для РСУБД.
Я не согласен с проверкой db на уникальность, прежде чем делать вставку, округленное отключение к базе данных дважды не очень эффективно и, конечно, не масштабируется, если у вас большой объем трафика пользователя.