2013-04-25 5 views
2

В mysql documentation указано, что определенные операторы вызовут неявное коммитирование во время транзакции. Например:Как предотвратить неявное совершение mysql

CREATE TABLE foo (bar INT); 
START TRANSACTION; 
INSERT INTO foo VALUES (1); 
CREATE TEMPORARY TABLE mumble like foo; 
ALTER TABLE mumble modify bar INT UNSIGNED; 
ROLLBACK; 
SELECT * FROM foo; 

после отката, я получаю одну строку назад от обув - документация на самом деле говорит о том, что альтер таблица не должна вызывать неявное совершить, если вы используете ключевое слово временное, но ALTER TABLE ВРЕМЕННЫЙ Недопустимый синтаксис, и отбрасывание временной таблицы не вызывает неявной фиксации, поэтому я подозреваю, что есть только ошибка (по крайней мере, от 5.5.29)

В любом случае, что бы я хотел сделать чтобы mysql никогда не заключал неявно, но вместо этого отказывался/откатывался, если задана команда, которая вызовет неявное коммитирование.

Я подозреваю, что нет никакого способа сделать это, оглядевшись по сторонам, но я надеюсь, что ошибаюсь. Надеюсь, кто-то здесь знает :)

ответ

1

Другой Hacky подход, который я просто попытался успешно, чтобы получить создать таблицу DDL

SHOW CREATE TABLE `tableName` 

Затем сделать несколько регулярных выражений магии с помощью MySQL конкретной команды и выработать новый запрос DDL который создаст временную таблицу на основе исходной таблицы, при этом все изменения таблицы изменений будут включены в таблицу create.

В моем проекте на PHP я сделал следующее, чтобы добавить уникальный индекс во временную таблицу.Он сделал трюк, и больше не было неявного совершения в середине транзакции.

$createDDL = ... get from SHOW CREATE TABLE `tableName` 
$nr = 0; 
$createDDL = preg_replace("/CREATE TABLE `$tableName` \(/", "CREATE TEMPORARY TABLE `$tmpName` (\nUNIQUE `ukey-1` ($uniqCols),", $createDDL, -1, $nr); 
if (!$nr) 
    throw new Exception("CREATE TABLE replacement error. No reps made."); 
mysqli_query($con, $createDDL); 

EDIT Кстати вот некоторые ошибки сообщения (функция) (в течение многих лет). В первом вы можете увидеть ответ (знакомства с 2006), что государства: так это поведение такое же, как и в БД Oracle, это соответствует один ...

Возможно, потребуется инициировать запрос функции «спам-кампания», чтобы этот запрос функции ожил!

+0

право, это обходной путь, я закончил делать что-то похожее - действительно надеюсь, что будет какой-то способ сделать это, но он появляется из отчетов об ошибках они также не планируют его исправлять. Спасибо, что нашли их. –

0

По крайней мере, с MySQL 5.5.19 вы правы. Заявки на документацию ALTER TEMPORARY TABLE не будут выполнять явное коммитирование, но MySQL дросселирует ключевое слово TEMPORARY.

я могу думать о двух возможных путей их устранения:

Способ 1:

Используйте новую временную таблицы вместо ALTER:

CREATE TABLE foo (bar INT); 
START TRANSACTION; 
INSERT INTO foo VALUES (1); 
CREATE TEMPORARY TABLE mumble LIKE foo; 
CREATE TEMPORARY TABLE mumble2 (bar INT UNSIGNED) SELECT * FROM mumble; 
ROLLBACK; 
SELECT * FROM foo; 

Последнее утверждение дает следующий результат :

Empty set (0.00 sec) 

К сожалению, нет возможности переименовать mumble2 обратно в mumble, так как RENAME не разрешен для временных таблиц, а ALTER mumble2 RENAME mumble неявно фиксируется.

Обход 2:

Не использовать временные таблицы, но вместо того, чтобы породить подпроцесс для выполнения команд, которые могут вызвать неявное обязательство:

Процесс 1:

CREATE TABLE foo (bar INT); 
START TRANSACTION; 
INSERT INTO foo VALUES (1); 

Процесс 2 (и использование другого соединения с MySQL):

CREATE TABLE mumble LIKE foo; 
ALTER TABLE mumble modify bar INT UNSIGNED; 

Процесс 1:

ROLLBACK; 
SELECT * FROM foo; 
DROP TABLE IF EXISTS mumble; 
+0

Обходные пути кажутся разумными для моего примера, но то, что я действительно ищу, является более общим решением проблемы. Я не думаю, что mysql должен неявно совершать транзакции во время транзакции, или если это произойдет, должен быть какой-то способ (безопасный режим/например.), Чтобы сказать ему откат и ошибку, а не делать это. –

+0

Согласен. Документы предполагают, что MySQL не должен принудительно фиксировать при выполнении * каждого * оператора DDL, содержащего таблицы TEMPORARY, поэтому, возможно, это было исправлено в более новой версии. Давайте пересечь наши пальцы! –

+0

К сожалению, не зафиксировано в 5.6.11, я не уверен, что ошибка открыта. И я не нашел способ отключить неявное совершение ... – basos

Смежные вопросы