Здравствуйте! Выполняется ли хранимая процедура в PostgreSQL (язык pl/pgsql) в рамках одной транзакции. Пример: создаю хп, в теле два запроса на вставку значений в таблицы, также вызываю в теле процедуры другую хп, в которая также модифицирует строки различных таблиц. Вопрос: при неудачной операции в какой-либо из выше перечисленных цепочек (н/р вставка null в поле NOT NULL в какой-либо из таблиц) произойдет ли полный откат всех предыдущих измпенений? Или в теле исходной хп надо вручную открывать, а затем открывать транзакцию? И еще один вопрос по автоинкременту. В таблице есть поле ID INTEGER PRIMARY KEY NOT NULL DEFAULT nextval('my_sec'); В х/п вставляю запись в эту таблицу и получаю ID вставленной записи с помощью функции currval('my_sec') для дальнейшего использования. Вопрос: если в момент между тем как я вставил новую запись и извлекаю currval('my_sec') другой пользователь вставляет новую запись в туже таблицу, не получу ли я значение my_seq (в первом случае) увеличенную не на 1, а на 2? Понимаю, что этого не будет если я явно открою транзакцию полностью для хп, но если хп автоматически открыват транзакцию и закрывает ее в конце, не хочу открывать ее дважды т.к. транзакции довольно ресурсоемка, а мне надо максимально оптимизировать бд. Спасибо.
AdmiralMontana Не уверен, но по-моему, оба варианта одинаковы. Внешняя транзакция в любом случае откатит все изменения, иначе это косяк БД. Но и внутренняя транзакция каши не испортит, ибо транзакция является "ресурсоемкой" только в случае ROLLBACK, а в случае коммита вложенной транзакции ровным счетом ничего делать не нужно. Если скорость БД так критична - не уверен, что постгрес является наилучшим выбором. Я нередко читал, как его ругают именно за скорость.
Функции работают внути одной "внешней" транзакции, т.е. ошибка в функции откатывает все сделанные изменения. Вложенные функции так же откатят все, включая изменения внешней функции. Но! В pl/pgsql есть возможность ловить исключения (BEGIN .. EXCEPTION ... END) - если применена такая конструкция, но на BEGIN реализуется SAVEPOINT, и ошибка откатит только изменения текущего блока. Так как блоки могут быть вложенные - получается типа вложенных транзакций. Подробнее в документации. Открыть транзакцию два раза у вас и не получится. В постгресе используются SAVEPOINT, а два раза сказать BEGIN низя. По автоинкременту. Счетчик глобальный, но его значение хранится привязанное к сессии (коннекту). Именно по-этому неполучится получить currval только установив сессию - будет ошибка, что счетчик не определен. На nextval изменяется глобальный счетчик атомарно и в сессию записывается текущее значение. Пока в этой сессии снова не будет применет nextval - он не изменится. PS: постгрес быстрый, особо на нормальном многоядровом железе.
Cпасибо за ответы. Dagdamor если не posgresql, какую бд посоветуешь? в mysql плохо реализованы транзакции, а мне важна устойчивость бд.
AdmiralMontana всяк кулик свой шесток хвалит. у меня есть знакомый весьма крутой прогер, по моей оценке. Прогит только под mssql. Уважает ее.
igordata, я читал про тип таблиц InnoDB(кажется так называется точно не помню) в MySQL, но пишут, что транзакции и там неважно реализованы, нет вложенных транзакций, и что MySQL вообще менее стабильна. Вообщем нужна такая субд, которая бы обеспечивала стабильность (ну и скорость) в многопользовательской и активно изменяющейся бд. MySQL подойдет? или PostgreSQL?
ХП - тут постгря в не конкуренции. Скорость запросов в MySQL MyISAM таблицах выше на порядок при выборке данных, так что если у вас проект в основном SELECT'ы использует, то имеет смысл ставить MySQL. В остальных случаях постгря получше будет ---------- Египет
Поддерживаю. Не замечал что-то охренительного быстродействия мускуля по сравнению С... При правильно построенной таблице и расставленных индексах, из таблицы с ~ 6 000 000 данных, выборка идет за какие-то несчастные миллисекунды. Пруф не приведу, ибо фпадлу. Но сам недавно столкнулся с этим =) Так что все перед глазами