2012-10-31 14 views
19

L'errore completo èActiveRecord errore: SAVEPOINT active_record_1 non esiste

ActiveRecord::StatementInvalid: Mysql2::Error: SAVEPOINT active_record_1 does not exist: ROLLBACK TO SAVEPOINT active_record_1 

Sto scrivendo una prova di unità e di ottenere questo errore ogni volta che provo a creare un nuovo oggetto ActiveRecord - ma solo dopo un certo punto. Ciò si verifica dopo queste righe:

ActiveRecord::Base.connection.execute "DROP TABLE IF EXISTS foo" 
ActiveRecord::Base.connection.execute "CREATE TABLE foo (id INTEGER PRIMARY KEY)" 

(La tabella 'foo' verrà popolato con i dati se il mio test ha esito positivo)

Prima le righe precedenti, posso scrivere qualcosa di simile

User.create(email => '[email protected]') 

e tutto funziona bene. Tuttavia, se provo a scrivere la riga precedente dopo la mia chiamata ad ActiveRecord :: Base.connection.execute, ottengo questo errore SAVEPOINT descritto sopra. Ho anche provato a inserire le mie istruzioni execute all'interno di una transazione, ma ciò non ha aiutato. Sono perplesso.

CRONACA - sto usando Rails 3.2.8

risposta

16

si utilizzano istruzioni Mysql DDE (create/drop/truncate table) che comporterà uno implicit commit.

A causa dell'impegno implicito, tutti i punti di salvataggio della transazione corrente vengono eliminati (consultare la documentazione precedente).

Per aggirare questo, è possibile turn off transactions e utilizzare DatabaseCleaner (modalità di troncamento).

1

È possibile utilizzare "TEMPORANEO" quando si creano/eliminano tabelle.

http://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html ALTER TABLE, CREATE TABLE e DROP TABLE non eseguono il commit di una transazione se viene utilizzata la parola chiave TEMPORARY. (Questo non si applica ad altre operazioni su tabelle temporanee come CREATE INDEX, che causano un commit.) Tuttavia, anche se non si verifica alcun commit implicito, non è possibile eseguire il rollback dell'istruzione. Pertanto, l'utilizzo di tali istruzioni violerà l'atomicità della transazione: ad esempio, se si utilizza CREATE TEMPORARY TABLE e si esegue il rollback della transazione, la tabella rimane in esistenza.

7

Per risolvere questo problema ..

config.use_transactional_fixtures = falsi

1

Giusto per chiarire. È possibile isolare i test che attivano le istruzioni MySQL DDE nel proprio file e quindi racchiudere config.use_transactional_fixtures = false in tale file. In questo modo tutti gli altri test non saranno interessati. Ora sei responsabile della pulizia in quel file di test isolato.

+0

Come si fa? –

Problemi correlati