<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#ffffff">
Hola Javier.<br>
<br>
Yo pensaba que lo del absolutePosition funcionaba, aunque sí es
cierto que a veces ha dado problemas. Imagino que antes de usar el
recordset llamas al método start() y al final al método stop()....
(por si acaso).<br>
<br>
En cualquier caso, si cierras y vuelves a crear el statement, lo veo
bien. No creo que sea lento, y en cualquier caso dudo que se note.<br>
Lo de cerrar los cursores binarios, recuerdo que lo intenté, pero
fallaba más por que el cursor ya no era válido que porque se quedara
abierto. Al cerrar la sesión, los cursores binarios se cierran
automáticamente, así que opté por dejarlo abierto.<br>
<br>
Si con lo que has hecho ya no aparecen errores, enhorabuena, creo
que habrás resuelto uno de los bugs más escondidos!! :-)<br>
<br>
Saludos, y pruebalo bien, a ver si para la 1.11 lo podemos meter en
el trunk.<br>
<br>
Fran.<br>
<br>
El 21/10/2010 16:50, Javier Estévez escribió:
<blockquote
cite="mid:AANLkTimfPhy1T93aAygScBB_tEENnmf+muqHRg=AVj4J@mail.gmail.com"
type="cite">Hola.<br>
<br>
Trabajando en el desarrollo de una extensión me he encontrado con
un problema al recuperar datos de una capa de PostGIS de más de
30000 elementos. Mi extensión recupera el valor de un campo
concreto de la tabla en una fila dada, para lo que uso un código
que ya había utilizado en múltiples otras ocasiones sin ningún
problema:<br>
<br>
idx = recordset.getFieldIndexByName(fieldName);<br>
if (idx > -1) {<br>
Value val =
recordset.getFieldValue(rowPosition, idx);<br>
.....<br>
}<br>
<br>
Mientras la fila en cuestión esté entre las primeras 5000 no hay
ningún problema, pero a partir de ahí empiezan a surgir errores al
obtener el dato a través de getFieldValue, concretamente en la
función setAbsolutePosition, en la clase PostGisDriver de extJDBC.
Tras indagaciones en el driver de PostGIS he podido comprobar que
se da cuando el dato solicitado no se encuentra en el cursor que
se está utilizando actualmente para obtener los datos en formato
binario y de forma más ágil, concretamente al tratar de crear un
nuevo cursor para obtener los datos.<br>
<br>
Descubrí que los cursores se generan en dos puntos del código: en
setData (para los primeros 5000 elementos) y en la mencionada
setAbsolutePosition (para el resto):<br>
<br>
En setData: <br>
<br>
st =
((ConnectionJDBC)conn).getConnection().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,<br>
ResultSet.CONCUR_READ_ONLY);<br>
// st.setFetchSize(FETCH_SIZE);<br>
myCursorId++;<br>
st.execute("declare " + getTableName() + myCursorId +
"_wkb_cursor binary scroll cursor with hold for " + sqlAux);<br>
rs = st.executeQuery("fetch forward " + FETCH_SIZE<br>
+ " in " + getTableName() + myCursorId +
"_wkb_cursor");<br>
fetch_min = 0;<br>
fetch_max = FETCH_SIZE - 1;<br>
<br>
Donde las variables son atributos de la clase: st es un Statement,
rs es un ResultSet y fech_min, fech_max y myCursorId son enteros.<br>
<br>
En setAbsolutePosition se utilizan esos mismos atributos:<br>
<br>
// calculamos el intervalo correcto<br>
fetch_min = (index / FETCH_SIZE) * FETCH_SIZE;<br>
fetch_max = fetch_min + FETCH_SIZE - 1;<br>
// y cogemos ese cacho<br>
rs.close();<br>
myCursorId++;<br>
st.execute("declare " + getTableName() + myCursorId +
"_wkb_cursorAbsolutePosition binary scroll cursor with hold for "
+ sqlTotal);<br>
st.executeQuery("fetch absolute " + fetch_min<br>
+ " in " + getTableName() + myCursorId +
"_wkb_cursorAbsolutePosition");<br>
<br>
rs = st.executeQuery("fetch forward " + FETCH_SIZE<br>
+ " in " + getTableName() + myCursorId +
"_wkb_cursorAbsolutePosition");<br>
<br>
<br>
Al utilizar la misma variable de tipo Statement en toda la clase,
me inclino a pensar que en alguna parte se ha inutilizado por
cualquier motivo, por lo que he probado a reiniciarlo en
setAbsolutePosition, metiendo la siguientes líneas (marcadas con
*) después del cierre del ResultSet:<br>
<br>
...<br>
rs.close();<br>
st.close(); *<br>
st =
((ConnectionJDBC)conn).getConnection().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,<br>
ResultSet.CONCUR_READ_ONLY); *<br>
myCursorId++;<br>
st.execute("declare " + getTableName() + myCursorId +
"_wkb_cursorAbsolutePosition binary scroll cursor with hold for "
+ sqlTotal);<br>
...<br>
<br clear="all">
Y así parece funcionar perfectamente. Pero como no sé muy bien qué
consecuencias tiene esto, planteo las siguientes preguntas:<br>
<br>
- ¿Puede existir algún problema de sincronía con los datos de la
BD?<br>
- ¿Es excesivamente ineficiente?<br>
- ¿Por qué se utiliza una única variable de tipo ResultSet y
Statement para (casi) todo?<br>
- Si cuando hay cambio de cursor se desecha el anterior para no
volverlo a utilizar, ¿no se debería cerrar (sentencia SQL CLOSE)?
<br>
<br>
No sé si me he liado demasiado al tratar de contar el tema. Espero
que podáis arrojar un poco de luz a todo este lío que me he
montado yo solo...<br>
<br>
Un saludo.<br>
<br>
<br>
-- <br>
Javier Estévez Valiñas<br>
Grupo de Desarrollo<br>
Cartolab - Laboratorio de Ingeniería Cartográfica<br>
<a moz-do-not-send="true" href="http://www.cartolab.es">http://www.cartolab.es</a><br>
<br>
ETS Ingeniería de Caminos, Canales y Puertos<br>
Universidade da Coruña<br>
Campus de Elviña - 15071 A Coruña (España)<br>
(34)981167000 ext. 5493<br>
<pre wrap="">
<fieldset class="mimeAttachmentHeader"></fieldset>
_______________________________________________
gvSIG_desarrolladores mailing list
<a class="moz-txt-link-abbreviated" href="mailto:gvSIG_desarrolladores@listserv.gva.es">gvSIG_desarrolladores@listserv.gva.es</a>
<a class="moz-txt-link-freetext" href="http://listserv.gva.es/cgi-bin/mailman/listinfo/gvsig_desarrolladores">http://listserv.gva.es/cgi-bin/mailman/listinfo/gvsig_desarrolladores</a>
</pre>
</blockquote>
<br>
<pre class="moz-signature" cols="72">--
Fran Peñarrubia
Scolab
<a class="moz-txt-link-abbreviated" href="http://www.scolab.es">www.scolab.es</a>
Asociación gvSIG
<a class="moz-txt-link-abbreviated" href="http://www.gvsig.com">www.gvsig.com</a>
</pre>
</body>
</html>