ROLLBACK, yeni oluşturulan hedef tablosuna INSERT yerleştirildikten sonra çalışmıyor


11

customers.csvMySQL tablo ( customers) içine CSV dosyasını ( ) ithal PHP-script üzerinde çalışıyorum .

CSV dosyası içeriğini mysql tablosuna eklemeden önce ilk olarak orijinal customerstabloyu yedekliyorum .

Ben bir mysql işlem (CSV ortasında bir yerde bozuk olduğu durumlarda ve ithalat atomik olduğundan emin olmak için) tüm ithalat işlemi (yedekleme dahil) sarma.

Sorun ROLLBACK hemen INSERT INTOifadeden sonra çağırırken çalışmıyor gibi görünüyor : phpMyAdmin üzerinden veritabanı kontrol ederken yeni oluşturulan tablo görebilirsiniz ve ROWS İÇİ hala geri roollback sonra mevcut .

İşlemlerin günlüğü:

[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" [] []

Neden acaba ROLLBACKarandığını merak ediyorum , işlem iptal edilmedi. Bunun CREATE TABLEdoğada işlemsel olmadığını ve geri alınamayacağını anlıyorum . Ancak, INSERT INTOsatır ekleme (şema tanımlamama) ile ilgili olduğu için, aslında işlemsel olacağından ve ROLLBACK'ten sonra boş hedef tabloyla bırakılacağımı varsayıyordum . Neden böyle değil?

Ve işte çıktı SHOW CREATE TABLE customers(benim masam 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

ve tasarım tablosu için çıktı:

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

Davranış, ilk olarak yeniden düzenlemek durumunda aynı mıdır create table, sonra start transaction, insert, rollback?
ypercubeᵀᴹ

Bunu söylemek üzereydim !!!
RolandoMySQLDBA

Programınızdaki bağlantıda otomatik komutu devre dışı bırakıyor musunuz?
mustaccio

Yanıtlar:


13

Bunun nedeni, bazı ifadelerin, CREATE TABLEörtük bir taahhüde neden olmasıdır. Bunları şu dokümanlarda okuyabilirsiniz: Örtük Bir Taahhüt Yapan İfadeler .

Yani orijinal ifade dizisi:

START TRANSACTION
SHOW TABLES LIKE customers
CREATE TABLE `customers__20150119_14_08_20` LIKE `customers`
INSERT INTO `customers__20150119_14_08_20` SELECT * FROM `customers`
ROLLBACK

genişleyecek:

START TRANSACTION ;   -- transaction context created
SHOW TABLES LIKE customers ;

COMMIT ;              -- CREATE TABLE forces commit before itself
                      --     (at this point the previous transaction is done.)
START TRANSACTION ;   -- and a new transaction  
CREATE TABLE `customers__20150119_14_08_20` 
    LIKE `customers` ;
COMMIT ;              -- CREATE TABLE forces commit after itself. 
                      -- At this point there's no transaction context

START TRANSACTION ;   --  starts a new transaction
INSERT INTO `customers__20150119_14_08_20` 
    SELECT * FROM `customers` ;
COMMIT ;              -- caused by "autocommit on" setting (guess). 

ROLLBACK ;            -- this rollback HAS NOTHING to undo

Çözüm, CREATE TABLEifadeden sonra işlemi başlatmak (veya yeni bir işlem) veya geçici bir tablo kullanmak olacaktır.


@Dimitry, düzenleme için teşekkürler.
ypercubeᵀᴹ

1
Ve nazik kelimeleriniz için @RolandoMySQLDBA. Ben bugün FGITW'im (ve sizden sadece 15 saniye daha hızlı;)
ypercubeᵀᴹ

@ ypercube hoş geldiniz! Tam olarak bu cause an implicit commitCREAT TABLE'ın nerede olacağını anlamaya biraz zaman aldı ... Yani bu taslağı yine de kağıda yapmak zorunda kaldım :) @RolandoMySQLDBA hızlı giriş için de teşekkürler. Geçen yıl birkaç düzinelerce cevap okudum ve bana çok yardımcı oldular !!
Dimitry K

Yani örtülü işlemek söylüyorsunuz önceINSERT de nasılsa bir taahhüt neden olur DDL deyimi neden olduğu sonrası ekin?
mustaccio

1
Evet, akıl yürütmede iki bölüm vardır, ancak bence ana bölüm, OP'nin çözemediği tabloyu oluşturma tablosunun örtülü taahhüdüdür.
ypercubeᵀᴹ

3

Görünüşe göre ifadelerin sırası soruna neden oluyor.

ACID işlem innodb içindeki eski yazı satır kilitleme , bir işlemi aralıklı olarak kesen 12 deyimleri adlandırdı. Sizin durumunuzda bu CREATE TABLEifadeydi.

Eğer koştum CREATE TABLEbir iç START TRANSACTION... COMMIT/ROLLBACKbloğuna, geri almak hiçbir çerçeve yoktu.

Sadece CREATE TABLEönce koş START TRANSACTIONve iyi olmalısın.

Bir şans ver !!!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.