Різниця між SET autocommit = 1 та START TRANSACTION у mysql (я щось пропустив?)


80

Я читаю транзакції в MySQL і не впевнений, чи правильно я зрозумів щось конкретне, і хочу бути впевненим, що я це правильно зрозумів, тому тут йдеться. Я знаю, що має робити транзакція, я просто не впевнений, зрозумів я семантику висловлювання чи ні.

Отже, моє запитання полягає в тому, чи щось не так (і, якщо це так, то що не так) із наступним:

За замовчуванням у MySQL увімкнено режим автокомісії.

Тепер SET autocommit=0;розпочне транзакцію, SET autocommit=1;буде неявно фіксувати. Це можливо COMMIT;, а також ROLLBACK;, в обох випадках автокомісія згодом все ще встановлюється на 0 (і нова транзакція неявно запускається).

START TRANSACTION;буде в основному, SET autocommit=0;поки a COMMIT;або ROLLBACK;не відбудеться.

Іншими словами, START TRANSACTION;і SET autocommit=0;еквівалентні, за винятком того факту, що START TRANSACTION;робить еквівалент неявного додавання SET autocommit=0;після COMMIT;абоROLLBACK;

Якщо це так, я не розумію http://dev.mysql.com/doc/refman/5.5/en/set-transaction.html#isolevel_serializable - бачачи, що наявність рівня ізоляції означає, що є транзакція, це означає, що автокомісія все одно повинна бути вимкнена?

І якщо є інша різниця (крім описаної вище) між початком транзакції та налаштуванням автокомітування, що це?

Відповіді:


81

Усвідомлення обробки транзакцій (автокомісія, явна та неявна) для вашої бази даних може позбавити вас від необхідності відновлення даних із резервної копії.

Транзакції контролюють заяву (і) про маніпулювання даними, щоб переконатися, що вони є атомними. Будучи "атомною" означає, що транзакція або відбувається, або не відбувається. Єдиний спосіб сигналізувати про завершення транзакції в базі даних - використовувати COMMITабо ROLLBACKоператор або (згідно з ANSI-92, який, на жаль, не включав синтаксис для створення / початку транзакції, тому він залежить від постачальника). COMMITзастосовує зміни (якщо такі є), внесені в рамках операції. ROLLBACKігнорує будь-які дії, що мали місце в транзакції - дуже бажано, коли оператор UPDATE / DELETE робить щось ненавмисне .

Зазвичай окремі оператори DML (Вставлення, Оновлення, Видалення) виконуються в транзакції автоздійснення - вони фіксуються, як тільки оператор успішно завершується. Що означає, що немає можливості повернути базу даних до стану до того, як оператор буде запущений у таких випадках, як ваш. Коли щось піде не так, єдиним доступним варіантом відновлення є реконструкція даних із резервної копії (за умови наявності такої). В MySQL автокомміт на за замовчуванням для InnoDB - MyISAM не підтримує транзакції. Його можна відключити за допомогою:

SET autocommit = 0

Явна транзакція - це коли вираз (и) загортаються у явно визначений блок коду транзакції - для MySQL цеSTART TRANSACTION . Він також вимагає чітко зробленого COMMITабоROLLBACK заяви заяви в кінці транзакції. Вкладені транзакції виходять за рамки цієї теми.

Неявні транзакції дещо відрізняються від явних. Неявні транзакції не вимагають чіткого визначення транзакції. Однак, як і явні транзакції, вони вимагають надання COMMITабо ROLLBACKвиписки.

Висновок

Явні транзакції є найбільш ідеальним рішенням - вони вимагають виписки COMMITабо ROLLBACK, щоб завершити транзакцію, і те, що відбувається, чітко заявляється, щоб інші могли прочитати, якщо буде потреба. Неявні транзакції - це нормально, якщо працювати з базою даних інтерактивно, алеCOMMIT твердження слід вказувати лише після перевірки результатів та ретельного визнання їх дійсними.

Це означає, що ви повинні використовувати:

SET autocommit = 0;

START TRANSACTION;
  UPDATE ...;

... і використовувати лише COMMIT;тоді, коли результати правильні.

Тим не менш, оператори UPDATE та DELETE зазвичай повертають лише кількість уражених рядків, а не конкретні деталі. Перетворіть такі твердження в оператори SELECT та перегляньте результати, щоб переконатися в правильності перед спробою оператора UPDATE / DELETE.

Додаток

Оператори DDL (мова визначення даних) автоматично фіксуються - вони не потребують оператора COMMIT. IE: Таблиця, індекс, збережена процедура, база даних та оператори створення або зміни подання.


9
Ого, це було швидко :-) Велике спасибі! Я не зовсім розумію, чому мені потрібно ВСТАНОВИТИ autocommit = 0; у наведеному вище прикладі; чи не означає це початок транзакції? А якщо ні, яка різниця?
ralokt

1
@tkolar: Вимкнення автокомісії змушує всіх користуватися ПОЧАТОК ОПЕРАЦІЇ; не всі усвідомлюють, що їм слід цим користуватися. 'Звичайно, інший DBA також може його знову ввімкнути ...
OMG Ponies

3
Думаю, мати SET autocommit = 0;лише перевагу, щоб не забути користуватися трасакцією
Тимо Хуовінен

Отже, коли я явно починаю транзакцію START TRANSACTION, я також повинен чітко вказати, що COMMITнавіть автокомісія увімкнена. Є це?
tomwang1013

У вкладеній збереженій процедурі Виклик. Що слід використовувати @OMGPonies
selvakumar

20

У InnoDB у вас є START TRANSACTION;, що в цьому механізмі є офіційно рекомендованим способом здійснення транзакцій, а не SET AUTOCOMMIT = 0;(не використовуйте SET AUTOCOMMIT = 0;для транзакцій в InnoDB, якщо це не для оптимізації транзакцій лише для читання ). Здійснити з COMMIT;.

Ви можете використовувати SET AUTOCOMMIT = 0;в InnoDB для випробувальних цілей, а не саме для угод.

У MyISAM у вас немає START TRANSACTION;. У цьому механізмі використання SET AUTOCOMMIT = 0;для транзакцій. Здійснити з COMMIT;або SET AUTOCOMMIT = 1;(Різниця пояснюється в коментарі до прикладу MyISAM нижче). Ви можете робити транзакції таким чином і в InnoDB.

Джерело: http://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_autocommit

Приклади транзакцій загального користування:

/* InnoDB */
START TRANSACTION;

INSERT INTO table_name (table_field) VALUES ('foo');
INSERT INTO table_name (table_field) VALUES ('bar');

COMMIT; /* SET AUTOCOMMIT = 1 might not set AUTOCOMMIT to its previous state */

/* MyISAM */
SET AUTOCOMMIT = 0;

INSERT INTO table_name (table_field) VALUES ('foo');
INSERT INTO table_name (table_field) VALUES ('bar');

SET AUTOCOMMIT = 1; /* COMMIT statement instead would not restore AUTOCOMMIT to 1 */

1

https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html

Правильним способом використання LOCK TABLES і UNLOCK TABLES з таблицями транзакцій, таких як таблиці InnoDB, є початок транзакції з SET autocommit = 0 (не ЗАПУСК ТРАНЗАКЦІЇ), за яким слід LOCK TABLES, і не викликати UNLOCK TABLES, доки транзакція не буде здійснена. явно. Наприклад, якщо вам потрібно написати в таблицю t1 і прочитати з таблиці t2, ви можете зробити це:

SET autocommit=0;
LOCK TABLES t1 WRITE, t2 READ, ...;... do something with tables t1 and t2 here ...
COMMIT;
UNLOCK TABLES;

Хтось знає, чому саме настільні замки працюють лише з, autocommit=0але не з START TRANSACTION? Мені це здається абсолютно довільним. Чи є технічна причина?
jlh

1

Якщо ви хочете скористатися відкатом, використовуйте старт транзакції і в іншому випадку забудьте всі ці речі,

За замовчуванням MySQL автоматично фіксує зміни в базі даних.

Щоб змусити MySQL не фіксувати ці зміни автоматично, виконайте наступне:

SET autocommit = 0;
//OR    
SET autocommit = OFF

Щоб явно ввімкнути режим автокомісії:

SET autocommit = 1;
//OR    
SET autocommit = ON;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.