2011-11-16 8 views
6

HAZIRLIYOR yapmak - Bir kez hazırlanan bir işlem daha sonra geri ile HAZIRLANMIŞ veya ROLLBACK sırasıyla HAZIRLAYAN COMMIT işlenen veya rulo olabilir. Bu komutlar not only the one that executed the original transaction.nasıl Postgres Belgeler gereğince İŞLEM çalışmalarını

Ben veritabanı tablolarına csv veri almak ve bunun için kullanıyorum çalışıyorum, herhangi bir oturumdan ihraç edilebilir COPY tablename [ (column [, ...]) ] FROM { 'filename' }

tüm bu bir kabuk komut dosyası yapılır

. Şimdi mesele ben psql komutu yürütmeden ve -c seçeneği aracılığıyla parametre olarak bu komutu geçirerek olmasıdır (ben komuta o komutu

prepare transaction 'some-id' aracılığıyla işlem başlatın).

Bir kayıt noktası oluşturmak ve tüm hataların örtmek kendisine geri almak istiyoruz. Kabuk komut birkaç diğer görevler sonra

, önceki psql'in deyimi ürettiler bu hatalarını kontrol ve ne zaman sonra komutunu

Prepared Rollback 'transaction-id' (ayrı psql command with sql statements olarak)

It kullanarak geri almak deneyin raporlarım kavramı yanlış alma veya süreç içinde bir şey eksik "No "transaction-id" found"

Am? Ben psql komut birden süresini veren am ve her yeni işlemde sonuçlanan çünkü

bunlar oluyor var mı? İçin

cevap

8

senin çalışmaya hazırlamak, COPY ve PREPARE aynı seansta olmalıdır. Sorunuzun beton komutları yoksun beri, varsayarak ediyorum size yazarken:

Hazırlanan

(ayrı psql'in sql ifadelere komuta) geri alma 'işlem kimliği' Sen kullandığınız farklı psql'i KOPYA ve HAZIRLIK komutları. Bu yanlış. KOPYA ve HAZIRLIK aynı oturuma birleştirin.

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 

diske anki hareketi yazma ve geçerli oturumda işlem sürecini çıkarak PREPARE TRANSACTION çalışır. Bu yüzden bir BEGIN'a ihtiyacınız vardır: hazırlamak istediğiniz işlemi başlatır. Prepeare tarafından etkilenmesini istediğiniz tüm komutlar, işlem başlatıldıktan sonra (sizin durumunuzda COPY komutu) gelmelidir. PREPARE TRANSACTION kesilirken, Şu anda bulunduğunuz işlem Verdiğiniz tanımlayıcı ile diske yazılır. İşlemin hazırlandıktan sonra yayınlanan tüm ifadeler artık işlemin bir parçası değildir. Bu nedenle BEGIN; PREPARE... ; COPY işlemi, COPY işlemini bir işlem olmaksızın çalıştırır.

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) 

Düzenleme::

İşte psql'in kabuğunda bir örnek Sen postgresql hazırlanan işlemlerini etkinleştirmesi gerekir.conf: max_prepared_transactions sıfırdır

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

ise psql'in işlem kimliği bulunmadı olduğunu bildiriyor, ancak bu özellik devre olma konusunda sizi uyarmaz. Psql, PREPARE TRANSACTION için bir uyarı verir, ancak kabuk komut dosyalarınız hazırlama ifadesinden sonra bir şeyler yazdırırsa kaçırılması kolaydır.

3

PREPARE TRANSACTIONiçin birden fazla boyunca genellikle işlem monitörleri veya benzer bir uygulama sunucusuna (örneğin EJB) tarafından kullanılan sunucuları işlemleri dağıtılır. Eğer ortada bir kayıt noktası istiyorsanız, SAVEPOINT some_name kullanmak

START TRANSACTION; 
COPY ....; 
COMMIT; 

ve sonra o kayıt noktasına geri alma edebilirsiniz:

Basitçe düzenli hareket kümesinden kopyanızı sarın.