Apakah INSERT mendapatkan komitmen otomatis?

13

Aplikasi kami meluncurkan kueri INSERT ke Database MySQL untuk menambahkan catatan. Saya ingin tahu apakah rekaman mendapatkan komitmen otomatis atau tidak. Jika saya menjalankan perintah ROLLBACK, kapan database melakukan rollback? Apakah ROLLBACK dapat dilakukan setelah KOMIT?

RPK
sumber
Hanya untuk klarifikasi, saya memberi tag sebagai 'innodb' 19 jam yang lalu, karena InnoDB menggunakan COMMIT / ROLLBACK.
RolandoMySQLDBA
Ini mendapat +1 untuk mengingatkan Pengembang dan DBA untuk memperhatikan perilaku transaksional, paradigma aplikasi yang mendukung transaksi, dan konsekuensinya (baik atau buruk).
RolandoMySQLDBA
Saya menjawab pertanyaan Anda dengan komentar di bawah jawaban saya.
RolandoMySQLDBA

Jawaban:

10

Jawaban untuk pertanyaan Anda tergantung pada apakah Anda dalam suatu transaksi yang akan mencakup lebih dari satu pernyataan. (Anda telah menandai pertanyaan dengan InnoDB, jawabannya akan berbeda dengan MyISAM.)

Dari manual referensi: http://dev.mysql.com/doc/refman/5.1/en/commit.html

Secara default, MySQL berjalan dengan mode autocommit diaktifkan. Ini berarti bahwa segera setelah Anda menjalankan pernyataan yang memperbarui (memodifikasi) sebuah tabel, MySQL menyimpan pembaruan pada disk untuk membuatnya permanen.

Jadi ya, secara default, jika Anda hanya menggunakan INSERT, catatan yang Anda masukkan akan dikomit, dan tidak ada gunanya mencoba mengembalikannya. (Ini secara efektif sama dengan membungkus setiap pernyataan antara BEGINdan COMMIT.)

Namun, jika Anda berurusan dengan transaksi secara eksplisit, Anda harus menggunakannya COMMITuntuk menyimpan catatan, tetapi Anda juga dapat menggunakannya ROLLBACK.

Anda dapat memulai transaksi secara eksplisit dengan menggunakan START TRANSACTION(atau BEGIN). Ini tidak tergantung pada autocommitpengaturan (diaktifkan secara default):

Dengan START TRANSACTION, autocommit tetap dinonaktifkan hingga Anda mengakhiri transaksi dengan COMMIT atau ROLLBACK. Mode autocommit kemudian kembali ke keadaan sebelumnya.

Atau, jika autocommit=0, saya pikir pernyataan apa pun yang mengikuti akhir transaksi, akan memulai transaksi (tetapi Anda masih dapat menggunakan START TRANSACTIONsecara eksplisit); setidaknya itulah cara saya menafsirkan ini :

Mode autocommit. Jika diatur ke 1, semua perubahan pada tabel segera berlaku. Jika diatur ke 0, Anda harus menggunakan COMMIT untuk menerima transaksi atau ROLLBACK untuk membatalkannya. Jika autocommit bernilai 0 dan Anda mengubahnya menjadi 1, MySQL melakukan COMMIT otomatis dari setiap transaksi terbuka. Cara lain untuk memulai transaksi adalah dengan menggunakan START TRANSACTION atau BEGIN statement. Lihat Bagian 12.3.1, “MULAI Sintaksis TRANSAKSI, KOMIT, dan ROLLBACK”.

Lebih khusus "cara lain untuk memulai transaksi" tampaknya menyiratkan bahwa pengaturan "autocommit = 0" sudah cukup untuk memulai transaksi (setidaknya tepat sebelum setiap pernyataan pada awal sesi atau yang mengikuti a COMMIT/ ROLLBACK). Saya akan menyarankan untuk menggunakan BEGINatau START TRANSACTIONtetap secara eksplisit meskipun autocommit=0, karena dapat membuatnya lebih jelas untuk melihat kapan transaksi dimulai atau berakhir.

(Bagaimana Anda memulai transaksi mungkin tergantung pada cara aplikasi Anda menggunakan MySQL.)

Bruno
sumber
1
Layak diberi +1 untuk protokol transaksional sepenuhnya.
RolandoMySQLDBA
@ Bruno, Untuk MyISAM di mana "komit" dan "kembalikan" tidak berfungsi, bukankah sisipan akan setengah dikomit?
Pacerier
7

Secara default, InnoDB diatur ke autocommit = 1 atau ON . Setelah berkomitmen, mereka tidak dapat dibatalkan .

Anda harus melakukan salah satu dari dua hal untuk menonaktifkannya di masa mendatang:

OPSI 1: Tambahkan ini ke /etc/my.cnf dan restart mysql

[mysqld]
autocommit=0

OPSI 2: Lakukan salah satu dari ini di DB Conenction terbuka sebelum memulai SQL yang bermakna

SET autocommit = 0;
START TRANSACTION;

Di bawah dua opsi ini, Anda harus melakukan COMMIT manual atau ROLLBACK manual .

CAVEAT

Jika tabelnya adalah MyISAM, maka penjelasannya lebih sederhana. Karena tidak ada transaksi untuk mesin penyimpanan MyISAM, semua INSERT, UPDATE, dan DELETE yang dijalankan adalah permanen. Tidak ada pengembalian apa pun.

RolandoMySQLDBA
sumber
Untuk klarifikasi tambahan, jawaban saya membahas mesin penyimpanan InnoDB dan MyISAM.
RolandoMySQLDBA
1
Untuk jaga-jaga, Komit Otomatis MATI di InnoDB dan aplikasi saya mengaktifkan Sisipkan Kueri, dan saya lupa mengeksekusi Komit, seberapa cepat perubahan hilang?
RPK
Jika aplikasi Anda secara manual meluncurkan sebuah KOMIT setelah setiap INSERT, itu ditulis dan tidak dapat dihapus. Jika Koneksi DB mati sebelum Anda Berkomitmen, semua perubahan hilang dan kembalikan terjadi. Jika Anda melakukan DDL (CREATE TABLE, DROP TABLE, ALTER TABLE, dll) atau secara manual mengeluarkan kunci tabel, INSERT akan di-autocommited. Jika Anda menggunakan MULAI TRANSAKSI, semua perubahan yang tidak dikomit dilakukan.
RolandoMySQLDBA
1
Mengenai "Jika Anda menggunakan MULAI TRANSAKSI, semua perubahan yang tidak dikomit akan dilakukan." (dalam konteks DDL, jika tidak akan dibatalkan), ada juga komit implisit sebelumnya (komit implisit adalah dari versi 5.5.3 menurut dokumentasi).
Bruno
1
"Jika Anda menggunakan MULAI TRANSAKSI, semua perubahan yang tidak dikomit akan dilakukan." - Saya mendapatkan gagasan itu dari Panduan Studi Sertifikasi MySQL 5.0 (ISBN 0-672-32812-7) yang menyebutkan nama MULAI TRANSAKSI, SET AUTOCOMMIT = 1, LOCK TABLES, UNLOCK TABLES, TRUNCATE TABLE, RENAME TABEL, MEJA RENAME, DROP INDEX, DROP TABLE , DROP DATABASE, BUAT INDEKS, BEGIN, dan ALTER TABEL di bawah judul "Dalam keadaan tertentu, transaksi saat ini dapat berakhir secara implisit: Jika Anda mengeluarkan salah satu dari pernyataan berikut, InnoDB secara implisit melakukan pernyataan sebelumnya yang tidak dikomit dari transaksi saat ini dan memulai transaksi baru ".
RolandoMySQLDBA