metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2011-12-27 02:19 pm

Внезапно: транзакции в Postgresql

Вот всю жизнь делаешь что-то, думаешь, что это очевидно, а потом берешь другую СУБД и оказывается, что там все сделано по другому.
Вот, например Postgresql vs Firebird:
1) В первом запросы отсылаются на сервер плейнтекстом, даже отпрепаренные с переменными. Во втором - сначала prepare, потом вызов полученного хендла с массивом параметров(бинарным) сколько надо раз. Впрочем, это может быть и особенность либы для доступа к Postgresql.
2) В первом транзакция одна на коннект, во втором - несколько на коннект.
3) В первом единственная ошибка в запросе в транзакции автоматом делает эту транзакцию невалидной целиком, и не дает ничего сделать до rollback. Во втором - транзакцию можно завершить, можно откатить, можно обработать ошибку и продолжить работать дальше. Не выполнится ровно один запрос. Чтобы имитировать такое в postgresql - нужно делать SAVEPOINT перед каждой query и откатываться на нее при ошибке.

Ну еще можно вспомнить про дотнет-драйвера обоих - в первом запрос-внутри-запроса выполнить невозможно, во втором свободно. Т.е. в postgresql "вычитать все шапки накладных, на каждую шапку вычитывая строки" - делается исключительно через жопие, методом "фетчим весь результат первого запроса, закрываем, затем выполняем второй сколько нужно раз".

[identity profile] filonenko-mikhail.blogspot.com (from livejournal.com) 2011-12-27 03:07 pm (UTC)(link)
Судя по api libpq отсыл подготовленных данных имеет две версии текстовую и бинарную. Использование текстовой версии является предпочтительным, так как для нее гарантируется совместимость с другими версиями. Наверно это также стратегическое решение для упрощения написания драйверов на хост-языках без внешних зависимостей.

Возможно некоторые из ваших желаний могут быть реализованы на 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

А кроссплатформенность - это да, миф.