2011-11-16 17 views
6

Come per Postgres Documentation - Una volta preparato, una transazione può essere successivamente confermata o ripristinata con COMMIT PREPARED o ROLLBACK PREPARED, rispettivamente. Questi comandi possono essere emessi da qualsiasi sessione, not only the one that executed the original transaction.Come eseguire PREPARE TRANSACTION lavoro

Sto cercando di importare dati da CSV in tabelle di database e per questo, sto usando la

COPY tablename [ (column [, ...]) ] FROM { 'filename' }

tutto questo è fatto in uno script di shell . Ora il problema è che sto eseguendo psql comando e passando questo comando come parametro tramite l'opzione -c (comincio transazione tramite il comando

prepare transaction 'some-id' in quel comando).

Desidero creare un punto di salvataggio e il rollback in caso di errori.

Dopo un paio di altre attività nella shell script, controllo per gli errori che la dichiarazione psql precedente hanno prodotto e quando poi cerco di rollback utilizzando il comando

Prepared Rollback 'transaction-id' (in separato psql command with sql statements)

E ' rapporti "No "transaction-id" found"

Sto ricevendo il concetto sbagliato o manca qualcosa nel processo?

Accade perché sto emettendo il comando psql più volte e ne risulta una nuova transazione?

risposta

8

Per prepararsi a lavorare, lo COPY e PREPARE devono essere nella stessa sessione. Dal momento che la tua domanda manca comandi concreti, sto supponendo che quando si scrive:

preparati Rollback 'transaction-id' (al comando psql separato con le istruzioni SQL)

Stai usando psql diverso comandi per COPY e PREPARE. Questo è sbagliato. Combina COPY e PREPARE nella stessa sessione.

E.g.

$ psql -c "BEGIN; COPY tablename FROM '/tmp/sql'; PREPARE TRANSACTION 'foobar';" db 
$ while /bin/not-ready-to-commit ; do sleep 1 ; done 
$ psql -c "COMMIT PREPARED 'foobar';" db 

I PREPARE TRANSACTION opere scrivendo la transazione corrente al disco e uscire dal processo di transazione nella sessione corrente. Ecco perché è necessario un BEGIN: avvia la transazione che si desidera preparare. Tutti i comandi che si desidera siano interessati dal prepear devono venire dopo l'avvio della transazione (nel caso specifico il comando COPY). Quando viene emesso lo PREPARE TRANSACTION, la transazione in cui ci si trova attualmente viene scritta su disco con l'identificativo che si fornisce. Eventuali dichiarazioni rilasciate dopo la preparazione della transazione non fanno più parte della transazione. Così facendo BEGIN; PREPARE... ; COPY si esegue l'operazione di copia senza una transazione.

Ecco un esempio in guscio psql:

demo=# DELETE FROM foo; 
DELETE 4 
demo=# BEGIN; -- start a transaction 
BEGIN 
DEMO=# COPY foo FROM '/tmp/sql'; -- do what you want to commit later 
COPY 4 
demo=# PREPARE TRANSACTION 'demo'; -- prepare the transaction 
PREPARE TRANSACTION 
demo=# ROLLBACK; -- this is just to show that there is no longer a transaction 
NOTICE: there is no transaction in progress 
ROLLBACK 
demo=# SELECT * FROM foo; -- the table is empty, copy waiting for commit 
a | b 
---+--- 
(0 rows) 
demo=# COMMIT PREPARED 'demo'; -- do the commit 
COMMIT PREPARED 
demo=# SELECT * FROM foo; -- data is visible 
a | b 
---+--- 
1 | 2 
3 | 4 
5 | 6 
7 | 8 
(4 rows) 

Edit: È necessario abilitare transazioni preparati in PostgreSQL.conf:

max_prepared_transactions = 1 # or more, zero (default) disables this feature. 

Se max_prepared_transactions è zero, psql riferisce che l'ID della transazione non viene trovato, ma non avvisa su questa funzione sia disattivata. Psql dà un avvertimento per PREPARE TRANSACTION ma è facile perdersi se gli script di shell stampano roba dopo la dichiarazione di preparazione.

3

PREPARE TRANSACTION è per distribuito transazioni attraverso multipla server, di solito utilizzati dai monitor di transazione o server applicazioni simili (per esempio EJB).

Basta avvolgere la vostra copia in un blocco di transazione regolare:

START TRANSACTION; 
COPY ....; 
COMMIT; 

Se si desidera un punto di salvataggio in mezzo, utilizzare SAVEPOINT some_name e quindi è possibile eseguire il rollback a quel punto di salvataggio.

Problemi correlati