PDO::query и транзакции

~
На сайте с 04.07.2006
Offline
82
934

В некоторых СУБД API, с которыми приходилось иметь дело, есть такая штука: если фунция типа query умеет обрабатывать несколько запросов, разделенных точкой с запятой, и сама СУБД поддерживает транзакции, то пачка запросов, засунутых в один query, отрабатывает как транзакция.

А как обстоят дела с PHP PDO::query? Есть ли какие-то гарантии относительно транзакционности загнанной пачки запросов, при условии что низлежащая СУБД умеет транзакции?

S
На сайте с 23.05.2004
Offline
315
#1

Транзакции и несколько запросов в одном query не имеют между собой ничего общего.

MySQL и SqLite обе поддерживают транзакции. Но первая работает только по правилу "1 запрос - 1 query", а вторая как раз может принят пачку в одном query. Грубо говоря тут все именно от базы зависит, а не от настройки посылающей запросы.

Но конструкция ниже будет работать одинаково.

transaction->start();

query();

query();

query();

transaction->commit/rollback();

Это просто подпись.
~
На сайте с 04.07.2006
Offline
82
#2
Stek:
Транзакции и несколько запросов в одном query не имеют между собой ничего общего.

А разве я утверждал обратное? Речь лишь о том, что в некоторых API так и сказано: "если засунуть несколько запросов, то они будут отработаны как транзакция", и ничего более.

Stek:
Но конструкция ниже будет работать одинаково.
transaction->start();
query();
query();
query();
transaction->commit/rollback();

Дело в том, что у меня есть тело query, в котором может быть как один запрос, так и несколько. Делать транзакцию безусловно не хочется - подозреваю что будет ненужный оверхед. Заглядывать внутрь query тоже не хочется. Хочется чтобы этот вопрос было каким-то образом унифицирован, типа если СУБД может транзакцию И в query несколько запросов, то пусть делает транзакцию.

S
На сайте с 23.05.2004
Offline
315
#3

Унификация - это когда в квери только 1 запрос. Про оверхед сильно сомневаюсь, основные усилия то уйдут на выполнение команды, а не на ее принятие. Можешь потестировать на простых запросах типа "select 1+1" без получения рекодсета. Может быть и выйграешь с десяток запросов при нескольких тысячах.

IL
На сайте с 20.04.2007
Offline
435
#4
~DEN~:
А как обстоят дела с PHP PDO::query?

Засунуть 2 запроса - первый нормальный, второй - бредовый, с ошибкой.. и посмотреть, выполнился ли первый - не?

~DEN~:
Делать транзакцию безусловно не хочется - подозреваю что будет ненужный оверхед.

Проще проверить, чем "подозревать"..

Ну и "до кучи" - в InnoDB всегда используются транзакции.. явно или неявно (см autocommit)

И ещё момент - использование нескольких запросов в одном PDO::query - часовая бомба.. Если один из запросов (кроме первого) выдаст ошибку, программа об этом не узнает - errorInfo ничего не покажет.

... :) Облачные серверы от RegRu - промокод 3F85-3D10-806D-7224 ( http://levik.info/regru )
Милованов Ю.С
На сайте с 24.01.2008
Offline
196
#5

ТС, как по мне, так это вообще того не стоит.

Зачем делать mysql_query(Query1;Query2);

Если можно 2 раза вызвать мускул_квери?

Да и к тому же, поддержка нескольких запросов в mysql_query снижает уровень безопасности.

mysql_query(SELECT * FROM `tbl1`; SELECT * FROM `tbl2` WHERE `id`='$id');

$id = "1';DROP database *** -- ";

Пример конечно банален, и пофикситься простым *_real_escape_string(), но все же. Почему именно несколько запросов в 1 квери? Чем это обусловлено?

Подпись))
~
На сайте с 04.07.2006
Offline
82
#6

Дело в том, что тело этого большого query берется из специального конфига. Там может быть и один запрос, и несколько. И содержимое может быть на любом PDO-драйвере, не обязательно MySQL.

Т.е. вы все советуете парсить содержимое, бить на раздельные запросы, делать 1 PDO::query на 1 запрос и организовывать транзакцию руками? А есть какая-то готовая функция для разбивки SQL-портянки? Ну если не считать explode.

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий