postgresql libpqxx: несколько запросов в одной транзакции - PullRequest
1 голос
/ 10 февраля 2020

При вставке / обновлении данных в postgresql легко выполнить несколько операторов в одной транзакции. (Моя цель здесь - избежать обхода сервера для каждого оператора, хотя изоляция транзакций часто бывает полезна.)

При запросах мне неясно, возможно ли это. Мне как-то нужно знать, какая функция будет потреблять каждый бит и как разделять биты.

connection c("dbname=test user=postgres hostaddr=127.0.0.1");
work w(c);
w.exec("SELECT a, b FROM my_table WHERE c = 3;");
w.exec("SELECT x, y, z FROM my_other_table WHERE c = 'dog';");
w.commit();

Предположим, у меня есть функции my_parse_function() и my_other_parse_function(), которые могут читать строки из каждого из этих запросов, я делал их отдельно.

1 Ответ

0 голосов
/ 12 февраля 2020

Если ваша цель состоит в том, чтобы избежать обходов, транзакции не помогают.

Изоляция транзакции в Postgres (как в большинстве СУБД) не зависит от сервера, выполняющего все ваши операторы одновременно , Каждый оператор в вашей транзакции будет отправлен и выполнен в момент вызова exec(); изоляция обеспечивается моделью управления параллелизмом механизма *1005*, позволяющей нескольким клиентам одновременно запускать команды и предоставляющей каждому из них различное представление о состоянии базы данных.

Если что-либо, заключает в себе последовательность операторов в транзакции добавится больше накладных расходов на связь, поскольку для выполнения команд BEGIN и COMMIT необходимы дополнительные обходы.


Если вы хотите выполнить несколько команд за один прием можно сделать, вызвав exec() с одной строкой из нескольких символов, разделенных точкой с запятой. Эти операторы будут неявно обрабатываться как одна транзакция, при условии, что явная транзакция уже не активна и что строка не содержит никаких явных команд BEGIN / COMMIT.

Если вы хотите отправлять несколько запросов , протокол позволяет возвращать несколько наборов результатов в ответ на строку с несколькими запросами, но exec() не дает вам доступа к ним; это просто оболочка для libpq PQexec(), которая отбрасывает все, кроме последнего результата.

Вместо этого вы можете использовать pipeline, который позволяет вам выдавать асинхронные запросы через insert(), а затем retrieve() результаты на досуге (блокируя до тех пор, пока они не появятся, если это необходимо). Установка предела retain() позволит конвейеру накапливать операторы, а затем отправлять их вместе в виде строки с несколькими командами.

...