Re[3]: БД и работа с исключительными ситуациями
От: IT Россия linq2db.com
Дата: 25.05.09 16:19
Оценка:
Здравствуйте, IB, Вы писали:

IB>Как следствие, гарантии от дубликатов здесь нет и по семантике это выражение эквивалентно IF EXISTS.


Если это так, то верить вообще никому нельзя и мир бы давно уже был в хаосе.
Если нам не помогут, то мы тоже никого не пощадим.
Re[8]: БД и работа с исключительными ситуациями
От: Tom Россия http://www.RSDN.ru
Дата: 25.05.09 16:20
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Tom, Вы писали:


Tom>>Единообразие всегдя хорошо, хотя бы потому что поддерживать просто

IB>не тот случай.. )

Tom>>Как я понимаю то же и для DELETE/UPDATE?

IB>Нет необходимости. По блокировкам они не совместимы и даже если получится INSERT-у или UPDATE-у вклиниться, то логическойй ошибки быть не должно.

Но всё равно пользователю надо сказать при удалении, что Person уже удалён, или что персон удалён при обновлении.
Или ты предлагаешь тут не испольщовать блокировки а по факту выполнения запроса проверять что он что то сделал?
Народная мудрось
всем все никому ничего(с).
Re[4]: БД и работа с исключительными ситуациями
От: Tom Россия http://www.RSDN.ru
Дата: 25.05.09 16:21
Оценка:
IT>Если сервер вменяемый, то парсить текст не надо. Должно хватить кодов ошибок.
Сервер стандартный, MS SQL 2008
Народная мудрось
всем все никому ничего(с).
Re[7]: БД и работа с исключительными ситуациями
От: wildwind Россия  
Дата: 25.05.09 16:28
Оценка: +1
Здравствуйте, Tom, Вы писали:

IMHO навороты вроде временных таблиц или пользовательских блокировок тут совершенно ни к чему. Стоимость поддержки явно превешивает достигнутый эффект.

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

В крайнем случае посмотреть на код ошибки (не текст!) и выкинуть "Возможно, такая персона уже есть, попробуйте снова".
Re[4]: БД и работа с исключительными ситуациями
От: IB Австрия http://rsdn.ru
Дата: 25.05.09 16:29
Оценка: 6 (1) -1 :)
Здравствуйте, IT, Вы писали:

IT>Если это так, то верить вообще никому нельзя и мир бы давно уже был в хаосе.

Дык, а у тебя еще иллюзии, что мир не в хаосе?
Щас я тебя вообще разочарую, даже оператор UPDATE физически выполняется в два приема, сначала SELECT, чтобы найти что менять, а уже потом непосредственно UPDATE. И межу этими SELECT-ом и UPDATE-ом тоже может что-нибудь пролезть.
Так что верить нельзя никому — мне можно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[9]: БД и работа с исключительными ситуациями
От: IB Австрия http://rsdn.ru
Дата: 25.05.09 16:33
Оценка: 5 (1)
Здравствуйте, Tom, Вы писали:

Tom>Но всё равно пользователю надо сказать при удалении, что Person уже удалён, или что персон удалён при обновлении.

В каком случае? Ты хочешь информировать пользователя, что не нашлось ни одной записи при вызове DELETE?
Ну, офигеть конечно какая полезная информация, но для этого достаточно вызвать @@ROWCOUNT, сразу после DELETE и все узнать без предварительного елозанья по таблице.

Tom>Или ты предлагаешь тут не испольщовать блокировки а по факту выполнения запроса проверять что он что то сделал?

Именно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[3]: БД и работа с исключительными ситуациями
От: Romanzek Россия  
Дата: 25.05.09 17:39
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Общий вопрос, допустим мы где то словили SqlException и даже распарсили текст и поняли что у нас произошла проблема с попыткой дважды добавить пользователя с одинаковым именем. Что дальше? Я предпологаю что надо выкинуть некоторое более специализированное исключение, но вот детали пока незнаю как сделать. А именно. Надо ли на каждый тип обьекта и операцию делать свой тип исключения, или для подобных проблем хватит одного типа исключения. Например, надо ли писать PersonNotFound/PersonAlreadyExists/... исключения или достатосного одного класса исключения для случая когда его обработка выливается в показ сообщения о ошибке.


Обработка исключений — это вообще отдельная тема. Как подходить к ее решению — зависит очень сильно от требований. В одном случае достаточно породить исключение на уровне бизнес-слоя и оставить так, в другом — родить целый механизм создания и обработки исключений с классификацией по уровням критичности, способам обработки и т.п.
Re: БД и работа с исключительными ситуациями
От: baranovda Российская Империя  
Дата: 26.05.09 14:03
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>В общем спасибо за мысли


Очевидно, что любая промышленная СУБД сама по себе слишком низкоуровневый инструмент, чтобы поддерживать операции трансформирования низкоуровневых исключений во внятные человекочитаемые сообщения. Но почти все современные СУБД поддерживают возможность метаописания объектов схемы и взаимоотношений между ними, чем можно и воспользоваться в слое бизнес-логики. Можно описать таблицы и колонки БД MSSQL, а затем натравить на базу кодогенератор, который пробежится по констрейнтам и индексам и смастерит автомат для самых типовых сценариев. Например:
1) На поле повешен уникальный индекс. Автомат должен сформировать код проверки наличия записи с таким ключом в схеме перед вставкой записи и кинуть исключение, текст которого будет склеен из строк метаописания таблицы и колонки, в которую пользователь пытается вставить недопустимое значение.
2) Пользователь пытается удалить запись, на которую есть ссылки, причем констрейнт не поддержживает каскадное удаление. Автомат перед удалением бежит в цикле по всем констрейнтам, получает все наименования Detail-таблиц, считает в них количество ссылок на запись в master-таблице, и, если таковое не равно нулю, клеит по метаописаниям строку типа "Невозможно удалить запись из таблицы 'Физические лица', поскольку с ней связано 10 записей в таблице 'Договоры'" и кидает исключение.
Re[5]: БД и работа с исключительными ситуациями
От: Romanzek Россия  
Дата: 26.05.09 14:10
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, IT, Вы писали:


IT>>Если это так, то верить вообще никому нельзя и мир бы давно уже был в хаосе.

IB>Дык, а у тебя еще иллюзии, что мир не в хаосе?
IB>Щас я тебя вообще разочарую, даже оператор UPDATE физически выполняется в два приема, сначала SELECT, чтобы найти что менять, а уже потом непосредственно UPDATE. И межу этими SELECT-ом и UPDATE-ом тоже может что-нибудь пролезть.
IB>Так что верить нельзя никому — мне можно.

Полный бред. Ничего там не пролезет и пролезть не может. На то и синхронизация делается. Запись сразу блокируется и уже потом выполняется ее обновление.
Если только СУБД какая-то самопальная.
Re[2]: БД и работа с исключительными ситуациями
От: Tom Россия http://www.RSDN.ru
Дата: 26.05.09 14:30
Оценка:
Здравствуйте, baranovda, Вы писали:

B>Здравствуйте, Tom, Вы писали:


Tom>>В общем спасибо за мысли


B>Очевидно, что любая промышленная СУБД сама по себе слишком низкоуровневый инструмент, чтобы поддерживать операции трансформирования низкоуровневых исключений во внятные человекочитаемые сообщения. Но почти все современные СУБД поддерживают возможность метаописания объектов схемы и взаимоотношений между ними, чем можно и воспользоваться в слое бизнес-логики. Можно описать таблицы и колонки БД MSSQL, а затем натравить на базу кодогенератор, который пробежится по констрейнтам и индексам и смастерит автомат для самых типовых сценариев. Например:

B>1) На поле повешен уникальный индекс. Автомат должен сформировать код проверки наличия записи с таким ключом в схеме перед вставкой записи и кинуть исключение, текст которого будет склеен из строк метаописания таблицы и колонки, в которую пользователь пытается вставить недопустимое значение.
B>2) Пользователь пытается удалить запись, на которую есть ссылки, причем констрейнт не поддержживает каскадное удаление. Автомат перед удалением бежит в цикле по всем констрейнтам, получает все наименования Detail-таблиц, считает в них количество ссылок на запись в master-таблице, и, если таковое не равно нулю, клеит по метаописаниям строку типа "Невозможно удалить запись из таблицы 'Физические лица', поскольку с ней связано 10 записей в таблице 'Договоры'" и кидает исключение.

Да, это тоже что пришло мне в голову — использвать кодогенератор. Тем более что он уже очень активно используется.
Народная мудрось
всем все никому ничего(с).
Re[6]: БД и работа с исключительными ситуациями
От: IB Австрия http://rsdn.ru
Дата: 26.05.09 14:58
Оценка:
Здравствуйте, Romanzek, Вы писали:

R>Полный бред.

Держи себя в руках, иначе за тебя это сделают другие..

R>Ничего там не пролезет и пролезть не может. На то и синхронизация делается.

Как именно делается, знаешь?

R>Запись сразу блокируется и уже потом выполняется ее обновление.

Ни когда не задавался вопросом, как именно блокируется и почему?

R>Если только СУБД какая-то самопальная.

В данном аспекте, как минимум MSSQL, DB2 и Sybase ведут себя похожим оразом, впрочем, как и любой внятный блокировочник.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[3]: БД и работа с исключительными ситуациями
От: Sergey T. Украина http://overstore.codeplex.com
Дата: 26.05.09 18:05
Оценка: 7 (1)
Здравствуйте, Tom, Вы писали:

Tom>Вот чего бы очень нехотелось — это парсинга текста исключения. По многим причинам:

Tom>1. Способ без какой либо поддержки компилятора
Tom>2. Нудно писать и тестировать

Tom>Общий вопрос, допустим мы где то словили SqlException и даже распарсили текст и поняли что у нас произошла проблема с попыткой дважды добавить пользователя с одинаковым именем. Что дальше? Я предпологаю что надо выкинуть некоторое более специализированное исключение, но вот детали пока незнаю как сделать. А именно. Надо ли на каждый тип обьекта и операцию делать свой тип исключения, или для подобных проблем хватит одного типа исключения. Например, надо ли писать PersonNotFound/PersonAlreadyExists/... исключения или достатосного одного класса исключения для случая когда его обработка выливается в показ сообщения о ошибке.


Парсить исключения — геморрой тот еще. Я пробовал. Оно даже работает, однако сообщения СУБД об ошибках могут быть локализованы (если я не ошибаюсь, МС СКЛ как раз такой сервер), а во-вторых, способ получения имени столбца таблицы, где произошла ошибка полезен до тех пор, пока у вас объекты имеют структуру идентичную таблице. Я вам предлагаю не парсить сообщение, а просто создать словарь вида "Текст исключения СУБД" — "Тип исключения + Сообщение об ошибке". Это, на мой взгляд, наиболее простой способ создать внятную обработку ошибок для ожидаемых ситуаций.
Список всех ошибок можно посмотреть (MS SQL 2005)
select * from sys.messages
There is no such thing as the perfect design.
Re[4]: БД и работа с исключительными ситуациями
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 26.05.09 18:24
Оценка: 1 (1)
Здравствуйте, IT, Вы писали:

IT>Если сервер вменяемый, то парсить текст не надо. Должно хватить кодов ошибок.


Код ошибки не поможет тебе понять, какой конкретно констрейнт сработал.
... << RSDN@Home 1.2.0 alpha 4 rev. 1226 on Windows Vista 6.1.7100.0>>
AVK Blog
Re[9]: БД и работа с исключительными ситуациями
От: IB Австрия http://rsdn.ru
Дата: 27.05.09 06:53
Оценка:
Здравствуйте, Tom, Вы писали:

IB>>Нет необходимости. По блокировкам они не совместимы и даже если получится INSERT-у или UPDATE-у вклиниться, то логическойй ошибки быть не должно.

Кстати, тут я прогнал. Теоретически, при UPDATE и DELETE тоже возможен конфликт, если доступ идет не по кластерному индексу.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[10]: БД и работа с исключительными ситуациями
От: Tom Россия http://www.RSDN.ru
Дата: 30.05.09 11:16
Оценка:
IB>Кстати, тут я прогнал. Теоретически, при UPDATE и DELETE тоже возможен конфликт, если доступ идет не по кластерному индексу.

А почему прогнал, можешь пояснить?
Народная мудрось
всем все никому ничего(с).
Re[11]: БД и работа с исключительными ситуациями
От: IB Австрия http://rsdn.ru
Дата: 01.06.09 08:44
Оценка: 12 (1)
Здравствуйте, Tom, Вы писали:

Tom>А почему прогнал, можешь пояснить?

Легко, заодно и юноше
Автор: Romanzek
Дата: 26.05.09
объясню, где он заблуждается.
Когда делается, скажем, UPDATE то порядок действия примерно следущий. Сначала на запись накладывается U блокировка, запись проверяется на соответствие предикату, после чего если запись подходит под удаление — блокировка конвертируется в X и производится собственно UPDATE.
Почему накладывается U? Очевидно, чтобы другие параллельные запросы могли эту запись читать (так как S совместима с U), пока текущая транзакция проверяет эту запись. Теперь представляем следующий сценарий:
T1:
UPDATE tbl SET Name = 'Димко' WHERE Name = 'Дмитрий Анатольевич' AND 
NOT EXISTS (SELECT 1 FROM tbl WHERE Name = 'Димко')


T2:
INSERT INTO tbl Name 
SELECT 'Димко' WHERE NOT EXISTS (SELECT 1 FROM tbl WHERE Name = 'Димко')


1. T1 блокирует U запись 'Дмитрий Анатольевич' и больше ничего, записи 'Димко' пока нет.
2. T2 выполняет SELECT и тоже ничего не блокирует, так как записей нет, а предикатные блокировки возможны только при SERIALIZABLE.
3. T1 добавляет запись 'Димко' удаляя 'Дмитрия Анатолича' со всеми положенными блокировками
4. T2 дожидается пока T1 отработает и вылетает по check constraint.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.