2012-03-15 21 views
11

Bir Postgres veritabanı kullanan bir Java uygulamasına sahibim ve veritabanımı büyütmek için PGPool'u tanıtmaya çalışıyorum. Postgres'in aşağıdaki hatayı attığı bir sorunla karşılaşıyorum: unnamed prepared statement does not exist. Günlük böylece pgpool bazı ekstra sorgular çalıştırır ayrıştırma/bağlama/yürütmek adımlar arasında,PGPool II'ye karşı Java sorguları "adsız hazırlanmış deyim yok" hatasına neden oluyor

EDTLOG: 00000: duration: 7.585 ms parse <unnamed>: "my select statement here" 
EDTLOG: 00000: duration: 0.088 ms bind <unnamed>: "my select statement here" 
EDTLOG: 00000: duration: 79.014 ms execute <unnamed>: "my select statement here" 

Ama bazen: Postgres üzerinde günlüğü cranking sonra aşağıdaki şeyler benim app yürütür seçin her tablo için neler görmek şuna benzer: Anladığım kadarıyla

EDTLOG: 00000: duration: 7.585 ms parse <unnamed>: "my select statement here" 
EDTLOG: 00000: duration: 0.088 ms bind <unnamed>: "my select statement here" 
EDTLOG: 00000: duration: 0.328 ms statement: SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.relname = 'my_table' AND c.relnamespace = n.oid AND n.nspname = 'pg_catalog' 
EDTLOG: 00000: duration: 79.014 ms execute <unnamed>: "my select statement here" 
EDTERROR: 26000: unnamed prepared statement does not exist 
EDTLOG: 00000: duration: 0.022 ms parse S_2: ROLLBACK 
EDTLOG: 00000: duration: 0.005 ms bind S_2: ROLLBACK 
EDTLOG: 00000: duration: 0.008 ms execute S_2: ROLLBACK 

, sorgu adsız sorgu yürütüldüğünde önce başka sorgusu o veritabanı oturumu sırasında gelirse o Postgres tarafından atılır alır isimsiz olduğu için. Bu nedenle, PGPool, ayrıştırma/sorgulama/yürütme adımları arasında bazen bu ek sorguları yayınladığından, sorgunun atılmasına neden olur.

İlk düşüncem belki de Java uygulamamın her sorgu için ayrıştırma/bind/execute ifadeleri göndermesi gerekmediğiydi. Ancak bu PostGres JDBC sürücüsü için JDBC sürüm 3 ve Postgres 7.4 http://jdbc.postgresql.org/documentation/head/server-prepare.html beri varsayılan davranışı gibi görünüyor. Sunucu tarafında hazırlanmış ifadeleri tamamen devre dışı bırakmayı deneyebilirim, ancak belgeler bunun nasıl yapılacağını belirtmiyor ve ben de bunun yapmak istediğim bir şey olduğundan emin değilim.

İkinci düşüncem PGPool II'nin bu meta veri sorgularını göndermeyi bırakmasıydı. PGPool'ü bir yük dengeleyici olarak kullanmaya çalıştığımdan, tablo meta verilerimle ilgili neden her şeyi bilmesi gerektiğini anlamıyorum. PGPool kaynağının is_system_catalog yönteminde bu sorguları yürüten kodu izledim: https://github.com/iakio/pgpool-II/blob/master/pool_select_walker.c#L256 PGPool, bazı nedenlerle tablo ilişkilerimi bilmek istiyor ve maalesef bu davranışı devre dışı bırakmanın bir yolunu görmüyorum.

Bu soruna geçici bir çözüm bulmak için gereken tüm bilgiler büyük beğeni kazanacaktır.

benim çevre ile ilgili bazı bilgiler:

JDBC Driver: postgresql-9.1-901.jdbc4.jar 
Java version "1.6.0_31" 
Spring 3.1 managed JPA 
Hibernate 3.5 
Postgres 9.1 

GÜNCELLEME: Ben sorununa geçici çözüm bulundu. JDBC URL'sine yerleştirerek temelde Postgres JDBC sürücüsüne sunucu tarafı tarafından hazırlanmış ifadeleri kullanmamasını söyler. Bu benim app veritabanımın önünde PGPool II kullanırken çalıştırmak için izin verir. Ben sadece PGPool kullanmak için sadece JDBC sürüm 2 protokolüne geri dönmek zorunda kaldığım gerçeği rahatsız.

+0

@Zecas Evet Sitenin nasıl çalıştığını biliyorum, bunu bana açıklamanıza gerek yok. Ben hala PGPool II'ye karşı en son JDBC sürümünü kullanmamı sağlayan bir çözümüm yok. Bildiğim kadarıyla bu hala açık bir sorudur. –

+0

Sorgularınızın bir işlem içinde çalıştığından emin olmak isteyebilirsiniz. Aynı bağlantıda başka bir işlem gelirse hazırlanan ifade atılır. Varsayılan olarak, postgresql jdbc sürücüsü işlemleri kullanmaz, ki bu bana biraz garip geliyor. Eğer geri çağırıyorsam, işlem davranışını persistence.xml içinde ayarlayabilirsiniz. – PlexQ

+0

Neden PgPool kullanıyorsunuz? Bağlantı havuzunu doğrudan uygulamanız içinden yönetmek için DBCP, BoneCP veya c3p0 kullanamaz mısınız? – Chochos

cevap

1

Ben sorununa geçici çözüm bulundu. JDBC URL'sinde protocolVersion = 2'yi yerleştirerek temelde Postgres JDBC sürücüsünü sunucu tarafı tarafından hazırlanmış ifadeleri kullanmamasını söyler. Bu benim app veritabanımın önünde PGPool II kullanırken çalıştırmak için izin verir. Ben sadece PGPool kullanmak için sadece JDBC sürüm 2 protokolüne geri dönmek zorunda kaldığım gerçeği rahatsız.

+2

Sunucu tarafında hazırlanmış ifadelerden kaçınmanın bir başka seçeneği de, 'prepareThreshold' parametresini gerçekten çok sayıda yürütme ile kullanmak olacaktır. –

-1

Hazırladığınız ifadeyi isimlendirirseniz nedir?

Ve başka bir soru ortaya çıkıyor: İhtiyacınız yoksa, neden hazırlanan ifadeleri kullanıyorsunuz?

Kolayca jdbc sürücüye karşı "normal" ifadelerini yapabilir ...

+0

Sadece JPA sorgularını kullanıyorum. Hazırda bekletme, hazırlanan ifadeler oluşturup bunları JDBC sürücüsüne gönderir. Ancak, PostgreSQL JDBC sürücüsü hakkında okuduklarımdan, Hazırlanmış Deyimler kullanmadan parametreli ifadeler yapmanın bir yolu yoktur. Ve bakalım, hemen hemen tüm sorguların parametreleri var. Hazırlanan ifadeleri, onları yaratan ben olmadığım için adlandıramıyorum, Hazırda bekle. –

İlgili konular