In che modo le transazioni SQL restituiscono risultati immediati?

3

Sto usando le transazioni per fare inserimenti / aggiornamenti in blocco. Questo è il mio piccolo ciclo di test:

$now = date('Y-m-d H:i:s');
for ($i=0; $i<60; $i++) {
    $db->insert($cfg['ps_manufacturer'], array(
        'reference' => 'MF'.$i,
        'name'      => 'MF NAME'.$i,
        'date_add'  => $now,
        'date_upd'  => $now,
        'active'    => true,
    ));
    echo $db->lastInsertId().'<br>';
}

Ora lo script sopra è ovviamente molto lento perché la query è in loop. Utilizzando le transazioni il tempo di esecuzione scende da 2s a 0.06s :

$db->beginTransaction();
$now = date('Y-m-d H:i:s');
for ($i=0; $i<60; $i++) {
    $db->insert($cfg['ps_manufacturer'], array(
        'reference' => 'MF'.$i,
        'name'      => 'MF NAME'.$i,
        'date_add'  => $now,
        'date_upd'  => $now,
        'active'    => true,
    ));
    echo $db->lastInsertId().'<br>';
}
$db->commit();

Ora, ciò che mi confonde è come fa il secondo campione a restituire immediatamente un ID di ogni riga inserita? Dalla mia comprensione la transazione inizia e accoda tutte le procedure, finché la coda non viene "rilasciata" utilizzando commit() .

Ora ovviamente il test ha dimostrato che ho torto, qualcuno potrebbe spiegare come funziona? Fa essenzialmente lo stesso, ma funziona molto più velocemente. L'utilizzo delle transazioni avvia una sorta di "sessione procedurale" ottimizzata per le continue interrogazioni? Questo codice è un po 'contro-intuitivo per me, sembra quasi una programmazione asincrona:)

    
posta gskema 15.09.2015 - 09:59
fonte

1 risposta

5

Qui ci sono due domande diverse, una sul comportamento delle prestazioni e una sugli ID generati automaticamente.

From my understanding the transaction starts and queues all procedures, until the queue is "released" by using commit()

Questo è solo parzialmente corretto. All'avvio della transazione, il database crea qualcosa come "un'istantanea privata" ed esegue immediatamente i tuoi inserimenti. Tutti gli altri utenti del database non vedranno le tue modifiche finché non chiami commit . Quindi il database può farlo normalmente nella memoria principale. Deve mantenere i tuoi inserimenti su un disco fisso solo una volta, così come deve garantire la coerenza con le operazioni concorrenti degli altri utenti solo una volta alla fine. Questo è il motivo per cui l'operazione funziona più velocemente di un commit dopo ogni "inserimento" (che è ciò che accade automaticamente nel tuo primo esempio).

E alla tua seconda domanda:

how does the second sample return an ID of every inserted row immediately?

Le colonne di incremento automatico vengono incrementate al di fuori dell'ambito della transazione . Vedi questo precedente post SO per una spiegazione.

    
risposta data 15.09.2015 - 10:30
fonte

Leggi altre domande sui tag