devolver un registro

04/10/2007 - 16:35 por Lars | Informe spam
Tengo varios servicios leyendo a la vez datos de una tabla. Con cada
registro hay que invocar a otro sistema. Los servicios ejecutan una query
con el registro que debe procesar. ¿Cómo puedo hacer para que no se devuelva
el mismo registro dos veces a servicios distintos?

Preguntas similare

Leer las respuestas

#1 Alberto Poblacion
04/10/2007 - 17:26 | Informe spam
"Lars" wrote in message
news:
Tengo varios servicios leyendo a la vez datos de una tabla. Con cada
registro hay que invocar a otro sistema. Los servicios ejecutan una query
con el registro que debe procesar. ¿Cómo puedo hacer para que no se
devuelva el mismo registro dos veces a servicios distintos?



Podrías añadirle a cada registro un campo booleano que indique
"yaLeido". Cuando vayas a leer, inicias una transacción, lees el registro
(con un "select ... where YaLeido=0") y le pones a true el bit, y haces un
commit (Lo de la transacción es para que se quede bloqueado mientras haces
esto, de forma que no lo lea otro servicio precisamente en ese momento).
Si no puedes modificar el registro, pero tiene algún identificador único
creciente (por ejemplo, una clave primaria de tipo Identity), puedes usar
una tabla auxiliar para guardar el Id del último registro procesado, y que
todos los servicios hagan un "select ... where Id>ultimoId". Y si no tienes
un identificador de este tipo, crea una tabla paralela de "registros ya
procesados" y en el Select pon un "...where not clave in
RegistrosProcesados". Obviamente, en todos los casos, usando una transacción
para controlar la concurrencia.
Respuesta Responder a este mensaje
#2 Lars
05/10/2007 - 00:34 | Informe spam
Muchas gracias Alberto.

Por ejemplo, utilizando un campo "YaLeido" en la tabla. ¿Existe la
posibilidad de que en una select se coja un registro y, antes de modificar
el valor "YaLeido" a true, entre otra select y lea el mismo registro? Es una
duda que tengo.
Me gustaría que no se asigna un mismo registro con un 100% de seguridad.

Gracias


"Alberto Poblacion"
escribió en el mensaje de noticias
news:%
"Lars" wrote in message
news:
Tengo varios servicios leyendo a la vez datos de una tabla. Con cada
registro hay que invocar a otro sistema. Los servicios ejecutan una query
con el registro que debe procesar. ¿Cómo puedo hacer para que no se
devuelva el mismo registro dos veces a servicios distintos?



Podrías añadirle a cada registro un campo booleano que indique
"yaLeido". Cuando vayas a leer, inicias una transacción, lees el registro
(con un "select ... where YaLeido=0") y le pones a true el bit, y haces un
commit (Lo de la transacción es para que se quede bloqueado mientras haces
esto, de forma que no lo lea otro servicio precisamente en ese momento).
Si no puedes modificar el registro, pero tiene algún identificador
único creciente (por ejemplo, una clave primaria de tipo Identity), puedes
usar una tabla auxiliar para guardar el Id del último registro procesado,
y que todos los servicios hagan un "select ... where Id>ultimoId". Y si no
tienes un identificador de este tipo, crea una tabla paralela de
"registros ya procesados" y en el Select pon un "...where not clave in
RegistrosProcesados". Obviamente, en todos los casos, usando una
transacción para controlar la concurrencia.

Respuesta Responder a este mensaje
#3 Alberto Poblacion
06/10/2007 - 09:39 | Informe spam
"Lars" wrote in message
news:
Por ejemplo, utilizando un campo "YaLeido" en la tabla. ¿Existe la
posibilidad de que en una select se coja un registro y, antes de modificar
el valor "YaLeido" a true, entre otra select y lea el mismo registro? Es
una duda que tengo.



Si no pones un boqueo, sí que podría pasar. Por eso te decía lo de
hacerlo todo dentro de una transacción. Al iniciar la transacción
(configurada en el modo Serializable), se van poniendo bloqueos en los
registros afectados. Sin embargo, el "Select" no se bloquea, por lo que
tienes que ser creativo con el SQL. Por ejemplo, en Sql Server 2005 podrías
hacer un UPDATE...OUTPUT, que sí que se bloquea con la transacción, y te
modifica el registro a la vez que te devuelve el dato:

update laTabla set YaLeido=1 OUTPUT deleted.* where codigo in (select
min(codigo) from laTabla where YaLeido=0)
Respuesta Responder a este mensaje
#4 Lars
11/10/2007 - 16:54 | Informe spam
Muchas gracias de nuevo Alberto. He tenido problemas con la conexión y hasta
hoy no he podido darte las gracias.


"Alberto Poblacion"
escribió en el mensaje news:u3BJbw%
"Lars" wrote in message
news:
Por ejemplo, utilizando un campo "YaLeido" en la tabla. ¿Existe la
posibilidad de que en una select se coja un registro y, antes de
modificar el valor "YaLeido" a true, entre otra select y lea el mismo
registro? Es una duda que tengo.



Si no pones un boqueo, sí que podría pasar. Por eso te decía lo de
hacerlo todo dentro de una transacción. Al iniciar la transacción
(configurada en el modo Serializable), se van poniendo bloqueos en los
registros afectados. Sin embargo, el "Select" no se bloquea, por lo que
tienes que ser creativo con el SQL. Por ejemplo, en Sql Server 2005
podrías hacer un UPDATE...OUTPUT, que sí que se bloquea con la
transacción, y te modifica el registro a la vez que te devuelve el dato:

update laTabla set YaLeido=1 OUTPUT deleted.* where codigo in (select
min(codigo) from laTabla where YaLeido=0)


email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida