Saya sedang mengerjakan skrip PHP yang mengimpor file CSV ( customers.csv
) ke dalam tabel MySQL ( customers
).
Sebelum memasukkan isi file CSV ke tabel mysql, saya pertama-tama membuat cadangan customers
tabel asli .
Saya membungkus seluruh proses impor (termasuk mencadangkan) dalam transaksi mysql (untuk menjelaskan kasus-kasus ketika CSV rusak di suatu tempat di tengah, dan untuk memastikan impor bersifat atomik).
Masalahnya adalah bahwa ROLLBACK tampaknya tidak berfungsi ketika saya memanggilnya setelah INSERT INTO
pernyataan: ketika memeriksa database melalui phpMyAdmin saya bisa melihat tabel yang baru dibuat DAN BARIS DI DALAMNYA masih ada setelah roollback .
Berikut log operasi:
[2015-01-19 14:08:11] DEBUG: "START TRANSACTION" [] []
[2015-01-19 14:08:11] DEBUG: SHOW TABLES LIKE :table_name; [] []
[2015-01-19 14:08:28] DEBUG: CREATE TABLE `customers__20150119_14_08_20` LIKE `customers` [] []
[2015-01-19 14:08:37] DEBUG: INSERT INTO `customers__20150119_14_08_20` SELECT * FROM `customers` [] []
[2015-01-19 14:08:50] DEBUG: "ROLLBACK" [] []
Jadi saya bertanya-tanya mengapa depsite ROLLBACK
disebut, transaksi tidak dibatalkan. Saya mengerti itu CREATE TABLE
bukan transaksional dan tidak dapat dibatalkan. Tapi saya berasumsi bahwa INSERT INTO
karena berurusan dengan memasukkan baris (tidak mendefinisikan skema), AKAN sebenarnya akan transaksional, dan setelah ROLLBACK saya akan dibiarkan dengan tabel tujuan kosong. Mengapa tidak demikian?
Dan inilah output SHOW CREATE TABLE customers
(jadi meja saya InnoDb
):
CREATE TABLE `customers` (
`Code` varchar(32) NOT NULL,
`Name` varchar(128) DEFAULT NULL,
`Price` varchar(128) DEFAULT NULL,
PRIMARY KEY (`Code`),
KEY `Price` (`Price`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
dan inilah output untuk tabel desination:
CREATE TABLE `customers__20150119_14_08_20` (
`Code` varchar(32) NOT NULL,
`Name` varchar(128) DEFAULT NULL,
`Price` varchar(128) DEFAULT NULL,
PRIMARY KEY (`Code`),
KEY `Price` (`Price`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
sumber
create table
, kemudianstart transaction, insert, rollback
?Jawaban:
Alasannya adalah bahwa beberapa pernyataan, seperti
CREATE TABLE
menyebabkan komit implisit. Anda dapat membacanya di dokumentasi: Pernyataan yang Menyebabkan Komitmen Tersirat .Jadi urutan asli dari pernyataan:
akan berkembang menjadi:
Solusinya adalah memulai transaksi (atau yang baru) setelah
CREATE TABLE
pernyataan atau menggunakan tabel sementara.sumber
cause an implicit commit
... Jadi harus melakukan garis besar ini di atas kertas :) @RolandoMySQLDBA terima kasih atas masukan yang cepat juga. Saya telah membaca beberapa lusin balasan Anda pada tahun lalu dan mereka banyak membantu saya !!INSERT
, disebabkan oleh pernyataan DDL, juga entah bagaimana menyebabkan komit setelah insert?Sepertinya urutan pernyataan yang menyebabkan masalah.
Dalam penguncian baris posting lama saya di innodb transaksi ACID , saya menyebutkan 12 pernyataan yang memecah transaksi sesekali. Dalam kasus khusus Anda, itu adalah
CREATE TABLE
pernyataan.Setelah Anda berlari
CREATE TABLE
di dalamSTART TRANSACTION
...COMMIT/ROLLBACK
blok, tidak ada kerangka untuk mengembalikan.Jalankan saja
CREATE TABLE
sebelumnyaSTART TRANSACTION
dan Anda harus baik-baik saja.Cobalah !!!
sumber