My jsme se s tim setkali u oracliho thin driveru pro 9.2. Kdyz clovek nezaviral resultsety, za chvili se server zacal zdrahat odpovidat na dotazy - stezoval si, ze "Too many open cursors".

Myslim, ze uzitecna sablona kodu je:

final ResultSet rs = stmt.executeQuery();
try {
   while ( rs.next() ) {
      processRow( rs );
   }
} finally {
   rs.close();
}

Osetrovani SQLException zaridite v nejakem vnejsim bloku try, prece to nebudete psat nekolikrat. Kdyz vylitne vyjimka v prvnim radku, nemate resultset a neni tedy ani co zavirat. Jakmile vsak resultset mate, tak ho urcite zavrete.
Ciste, prehledne.

Obcas se vidi takove veci jako:

ResultSet rs = null;
try {
   rs = stmt.executeQuery();
   while ( rs. next() ) {
      processRow( rs );
   }
} catch ( SQLException e ) {
e.printStackTrace(); } finally {
   if ( rs != null ) {
      try {
          rs.close();
      } catch ( SQLException e ) {
         e.printStackTrace();
      }
   }
}

- coz je proste silene.

Honza


Moravec Jan napsal:
U jakeho presne driveru jsem se s problemem nezavirani RS setkal si jiz 
nepamatuji. Dost mozna i ten zminovany Oracle OCI driver.

Ono zavisi hodne na kontextu a zpusobu pouziti PS a RS. Pokud napriklad otevirate z jednoho PS vice result setu, 
jak intepretovat ponekud vagni javadoc u Statement.close "When a <code>Statement</code> object 
is closed, its current <code>ResultSet</code> object, if one exists, is also closed."

Jaky z tech x otevrenych RS je ten "current"? Jsou to
a) vsechny
b) posledni otevreny
c) posledni iterovany

Jak jsem psal, PS jsou navic casto cachovany, takze pokud volate PS.close ve 
finaly, nemusi to ale VUBEC znamenat, ze se Vam zavrou result sety asociovane s 
tim PS, protoze jeho close metoda se v zaveru ani nezavola (zavola se close na 
nejakym wrapperu, ktere ten PS POUZE vrati do poolu).

Tj. shrnuto podtrzeno, RS zavirat vzdy explicitne a neni problem. Spolehat na 
PS.close/finalizator apod -> povesit programatora za usi do pruvanu.

Off topic: S tim Oracle driverem jsme mi pripomnel jinou perlu jejich driveru. 
Pri praci s LOBy se musely PS castovat na Oracle specificke implementace, aby 
bylo mozne volat metody pro praci s LOBy. Standardni java.sql.Clob/Blob 
nefungovaly. Doufam, ze uz s tim neco udelali... toto bylo pred cca 3 roky.

Honza

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Behalf Of Artur Linhart - Java Communication
Sent: Thursday, August 24, 2006 10:46 AM
To: Java
Subject: Re: for vs. while - problemy s SQL Drivery


.Myslim, ze s nejakym podobnym nestandardnim chovanim jsme se setkali v
pripade Oracle 9.2.0.1 driveru, ktere obsahovaly mimo jine i nekolik chybek
v tehle oblasti. Uz je to dele, ale problem byl mam dojem nejen s uzaviranim
pripojeneho resultsetu, ale i s tim, ze se sam statement neuvolnoval
korektne ackoliv by podle standardu mel pote co se spusti garbage
collector - urcite se vyplaci volat close primo na statementu stejne jako
predtim na resultsetu ktery byl pres statement vytvoren.

Prestoze javadoc u metody java.sql.Statement.close() tvrdi
 "A <code>Statement</code> object is automatically closed
     * when it is garbage collected. When a <code>Statement</code> object is
     * closed, its current <code>ResultSet</code> object, if one exists, is
     * also closed.  "
- nemusi byt obecne pravda ani prvni, ani druha veta, holt jako vzdy zalezi
na tom, jak se ten interface naimplementuje. Takze pokud si nejste
stoprocentne jisti (coz neni asi nikdy :-) ) tak by se ten close mel asi
volat vsude kde to jde...
Jinak - slo o oci8 driver, mozna ze u nativniho, ktery bohuzel pouzivat
nemuzeme, to funguje spravne, to nevim...

Uz je to sice hodne off topic od puvodniho tematu, ale napada mne napr.
mimodek i dalsi chyba na kterou jsme narazili v Oracle driverech se kterou
jsme se opravdu hodne hodne vyvztekali nez jsme na ni prisli - a to je
problem s datovym typem timestamp a jeho prevodem na javovsky Timestamp, u
ktereho se v pripade, ze je pocet milisekund nacteny z databaze 0 jako pocet
milisekund "naindukuje" jine cislo nezli 0.
Jinymi slovy, jak mi pomohl kolega Michal s upresnenim: pri cteni Timestamp
s 0 ms je vracena hodnota ms z posledniho cteneho Timestampu ktery mel ms <>
0. Jednoduse, pokud tam bylo 0 ms, tak ten driver jakoby ten udaj "ms" nijak
nemenil, takze tam zustala predesla hodnota.

 - tzn. pokud napr. pouzivate Oracle timestampy k overeni, jestli se Vam
zaznam nezmenil v mezidobi mezi dvema selecty, je dobre na podobne policko
pripojit primo na urovni databaze trigger, ktery nejenom ze pri updatu
nastavuje vzdy aktualni hodnotu casu, ale v pripade, ze pocet milisekund je
0, tak je trosicku postrci o milisekundu, aby nacitani pres JDBC do typu
Timestamp potom fungovalo spravne - my to delame momentalne takhle:

create or replace trigger TU_BC_COUNTRY
before update on BC_COUNTRY
for each row
declare
  locMs int;
  loc_current_GMT_timestamp TIMESTAMP(3);
begin
  loc_current_GMT_timestamp := current_timestamp at time zone 'GMT';
  :new.CHANGE_DATE := loc_current_GMT_timestamp;

  locMs := mod(extract(second from :new.CHANGE_DATE) * 1000, 1000);
  if (locMs = 0) then
    -- tady je to postrceni o milisekundu, pokud je pocet milisekund roven
0:
    :new.CHANGE_DATE := :new.CHANGE_DATE + numtodsinterval(0.001, 'SECOND');
  end if;

  :new.CREATE_DATE := :old.CREATE_DATE;
  :new.CREATE_USER_LOGIN := :old.CREATE_USER_LOGIN;
end;
/

neprisli jsme na jiny zpusob jak se s tim vyporadat.

U verze 10.2 oracle driveru snad uz je to opravene...


    Ahoj,

        Archie.

-..--- Original Message ----- From: "Roman Kratochvil" <[EMAIL PROTECTED]>
To: "Java" <konference@java.cz>
Sent: Wednesday, August 23, 2006 8:42 PM
Subject: Re: for vs. while


To, ze je to zrovna ResultSet, byl jenom priklad, o to mi primarne neslo.
Nicmene faktem je, ze jsem se zatim nesetkal (troufam si tvrdit) s JDBC
driverem, ktery by ty ResultSety nezaviral pri zavreni Statementu (ten
samozrejme zaviram ve finally...). Delal jsem s MSSQL2000, 2005 (drivery od
MS i jTds), MySQL 3.x, 4.x (drivery org.gjt.mm.mysql* i com.mysql.*), HSQLDB
1.7.x. Myslim, ze i s Oracle 8.5 nebyl problem, ale to uz je davno, mozna se
pletu (resp. mozna to tehdy bylo psane jinak). Mohl bych se poucit, s jakymi
DB/drivery jste zazili problemy?

Diky

Roman


----- Original Message ----- From: "Moravec Jan" <[EMAIL PROTECTED]>
To: "Java" <konference@java.cz>
Sent: Wednesday, August 23, 2006 5:29 PM
Subject: RE: for vs. while


No jo, ale ve finally ten RS nezavrete, kdyz to je lokalni promenna toho
cyklu. Takze v ty podobe v jake to bylo presentovano, tj.

for (ResultSet res=...; res.next(); )
{
}

je to spise hezky antipattern.

H.


-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Behalf Of Stanislav Ošmera
Sent: Wednesday, August 23, 2006 4:41 PM
To: Java
Subject: Re: for vs. while


On 8/23/06, Moravec Jan <[EMAIL PROTECTED]> wrote:
Zdravim,

Asi jsem neco nepochopil, ale jak korektne uzavrete ten otevreny result
set bez toho, ze byste spolehal na to, ze se to "mozna udela samo" pri
zavirani prepared statementu?

Nedoporucuji na prilis spolehat na to, ze se ResultSet uzavre v okamziku
uzavreni statementu (to rika javadoc u ResultSet.close).
Presne, drive jsem se na to spolehal az jsem jednou dost narazil a
musel to prepisovat vsude. Myslim mozna ze je to napsano i v tom
Blochovy ze resultset vzdy zavirat ve finally bloku, nikdy se
nespolehat na zadnou automatiku


--
Stanislav Ošmera
Work: +44 (0)2075 980 348
Cell: +44 (0)7914 635 412
private email: [EMAIL PROTECTED]
work email: [EMAIL PROTECTED]
Skype: sosmera   ICQ:149634231



Odpovedet emailem