Внезапно: транзакции в Postgresql
Dec. 27th, 2011 02:19 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Вот всю жизнь делаешь что-то, думаешь, что это очевидно, а потом берешь другую СУБД и оказывается, что там все сделано по другому.
Вот, например Postgresql vs Firebird:
1) В первом запросы отсылаются на сервер плейнтекстом, даже отпрепаренные с переменными. Во втором - сначала prepare, потом вызов полученного хендла с массивом параметров(бинарным) сколько надо раз. Впрочем, это может быть и особенность либы для доступа к Postgresql.
2) В первом транзакция одна на коннект, во втором - несколько на коннект.
3) В первом единственная ошибка в запросе в транзакции автоматом делает эту транзакцию невалидной целиком, и не дает ничего сделать до rollback. Во втором - транзакцию можно завершить, можно откатить, можно обработать ошибку и продолжить работать дальше. Не выполнится ровно один запрос. Чтобы имитировать такое в postgresql - нужно делать SAVEPOINT перед каждой query и откатываться на нее при ошибке.
Ну еще можно вспомнить про дотнет-драйвера обоих - в первом запрос-внутри-запроса выполнить невозможно, во втором свободно. Т.е. в postgresql "вычитать все шапки накладных, на каждую шапку вычитывая строки" - делается исключительно через жопие, методом "фетчим весь результат первого запроса, закрываем, затем выполняем второй сколько нужно раз".
Вот, например Postgresql vs Firebird:
1) В первом запросы отсылаются на сервер плейнтекстом, даже отпрепаренные с переменными. Во втором - сначала prepare, потом вызов полученного хендла с массивом параметров(бинарным) сколько надо раз. Впрочем, это может быть и особенность либы для доступа к Postgresql.
2) В первом транзакция одна на коннект, во втором - несколько на коннект.
3) В первом единственная ошибка в запросе в транзакции автоматом делает эту транзакцию невалидной целиком, и не дает ничего сделать до rollback. Во втором - транзакцию можно завершить, можно откатить, можно обработать ошибку и продолжить работать дальше. Не выполнится ровно один запрос. Чтобы имитировать такое в postgresql - нужно делать SAVEPOINT перед каждой query и откатываться на нее при ошибке.
Ну еще можно вспомнить про дотнет-драйвера обоих - в первом запрос-внутри-запроса выполнить невозможно, во втором свободно. Т.е. в postgresql "вычитать все шапки накладных, на каждую шапку вычитывая строки" - делается исключительно через жопие, методом "фетчим весь результат первого запроса, закрываем, затем выполняем второй сколько нужно раз".
no subject
Date: 2011-12-27 11:37 am (UTC)2 -- последовательно -- можно. Параллельно -- мало смысла с точки зрения практики -- негламурненько, но не мешает особо.
3 -- уёбищно, факт.
Про дотнет-драйвера -- а что, до сих пор работаете с БД не через итераты и аппликативные функторы?
no subject
Date: 2011-12-27 11:42 am (UTC)no subject
Date: 2011-12-27 11:44 am (UTC)Задача тупо "выполнить запрос, если он свалился - выполнить другой, который не свалится". Без всякого серверного кода, тупо из клиента. Хрен там.
no subject
Date: 2011-12-27 12:07 pm (UTC)no subject
Date: 2011-12-27 12:10 pm (UTC)no subject
Date: 2011-12-27 12:13 pm (UTC)А вот plpgsql умеет. В общем должно и всякое остальное уметь, но я не пробовал. Да, и я не знаю, как во всяком основном с транзакциями.
no subject
Date: 2011-12-27 12:14 pm (UTC)no subject
Date: 2011-12-27 12:09 pm (UTC)no subject
Date: 2011-12-27 12:10 pm (UTC)no subject
Date: 2011-12-27 12:28 pm (UTC)no subject
Date: 2011-12-27 12:18 pm (UTC)Фичей некоторых полезных нет - типа partitioning, репликации нормальной, итд итп. Из фич уровня языка разве что window functions не хватает, остальное весьма хорошо.
Со служебными средствами (человеческие логи, средства мониторинга, утилиты, текстовый бэкап) - печально, разработчики считают что это не нужно и занимаются больше внутренностями БД.
С документацией не очень хорошо. Комьюнити немного самоогороженное, нервничают когда про них пишут.
Очень удобна для мелких-средних проектов, с точки зрения программирования. Серверный код (императивное расширение sql) достаточно логично устроен, компонент доступа чуть более чем дохрена. Средств разработки под нее как бы не больше чем средств эксплуатации.
no subject
Date: 2011-12-27 12:45 pm (UTC)no subject
Date: 2011-12-29 01:54 am (UTC)Однако если сырцы триггеров и процедур из базы удалены - то конечно в таком случае текстовый бэкап не проканает.
no subject
Date: 2011-12-27 03:20 pm (UTC)no subject
Date: 2011-12-27 03:26 pm (UTC)no subject
Date: 2011-12-27 04:24 pm (UTC)no subject
Date: 2011-12-27 01:13 pm (UTC)no subject
Date: 2011-12-27 01:36 pm (UTC)no subject
Date: 2011-12-27 02:39 pm (UTC)no subject
Date: 2011-12-27 03:59 pm (UTC)no subject
Date: 2011-12-27 03:07 pm (UTC)Возможно некоторые из ваших желаний могут быть реализованы на plpgsql. Функции на данном языке могу возвращать множество столбцов и строк. В 9-ой версии появились анонимные процедуры, возвращающие void (как в оракле). http://www.postgresql.org/docs/9.0/static/sql-do.html
Есть exceptions, которые можно использовать в plpgsql. http://www.postgresql.org/docs/9.1/interactive/plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING
А кроссплатформенность - это да, миф.
no subject
Date: 2011-12-27 08:15 pm (UTC)Пункты 1/2/3 везде так, или только под дотнетом?
no subject
Date: 2011-12-27 08:16 pm (UTC)no subject
Date: 2011-12-27 08:17 pm (UTC)no subject
Date: 2011-12-27 11:07 pm (UTC)2) Да, TCP делает это лучшэ.
В первом запрос-внутри-запроса делается ровно как во всём остальном SQL:
делаешь JOIN (лучшэ OUTER, можно SUB-SELECT), order by ШАПКА, и складываешь всё до изменения этой шапки в её строки.