Bloqueo con SQL Select

975 views
Skip to first unread message

Osornino (Chile)

unread,
Oct 11, 2011, 11:38:00 AM10/11/11
to Comunidad de Visual Foxpro en Español
Hola a todos, una vez mas los molesto con mis dudas.

Como trabaja el SELECT SQL con los registros bloqueados?

Necesito crear un cursor con datos de varias "Cuentas" o
"Trabajadores" (no importa el tipo); existen innumerables registros.
(para todos los procesos = Buffer 3, Multilocks On)


Realizo un SELECT SQL, y me gustaria saber:

Que pasa con los registros bloqueados, SELECT SQL los procesa dentro
del cursor, los omite, envia un error al procesar?

Si alguien me puede indicar como es el comportamiento del SELECT SQL
en estos casos, se lo agradeceria.

Muchas gracias a todos por sus respuestas.

Victor Espina

unread,
Oct 12, 2011, 6:00:22 AM10/12/11
to publice...@googlegroups.com
El bloqueo en SQL es bastante mas complejo de lo que es en VFP. Basicamente, SQL maneja automaticamene los bloqueos, los cuales generalmente se crean al momento de actualizar una tabla y se liberan luego que los cambios son confirmados, bien sea implicitamente o explicitamente mediante un COMMIT.

SQL manejo multiples tipos de bloqueos, pero los mas comunes son los bloqueos por registro, pagina y tabla,  Un bloqueo por registro, como su nombre lo indica, solo afecta a un registro particular en una tabla dada; por su parte, un bloqueo por pagina afecta al registro modificado y a todos los demas registros almacenados en la misma pagina fisica. Finalmente, un bloqueo de tabla afecta a todos los registros de la tabla modificada.

El tipo de bloqueo aplicado en un caso particular depende de multiples factores, ligados estrechamente a la clausula WHERE indicada y a los indices disponibles.  Como regla general, cuando se hace un UPDATE o un DELETE sobre una tabla usando unicamente su primary key como WHERE, ej, DELETE FROM clientes WHERE codigo = ?cCodigo, SQL bloqueara solo el registro afectado.

En constraste, si la clausula WHERE implica mas de una columna y existe un indice definido para cada una de esas columnas, muy probablemente SQL aplicaa un bloqueo de pagina, pero si no existiera un indice creado para una o mas de las columnas mencionadas en el WHERE de un UPDATE o DELETE, entonces SQL aplicara un bloqueo a la tabla completa.

Que pasa si un usuario intenta actualizar un registro que esta bloqueado, bien sea especificamente, contenido en una pagina que esta bloqueada o en una tabla que esta bloqueada?  SQL esperara el tiempo indicado en su configuracion actual y luego de ese tiempo generara un error por bloqueo.

Hay alguna forma sencilla de validar si un registro especifico esta bloqueado?  lamentablemente en SQL no contamos con un equivalente para la funcion RLOCK() de VFP, asi que la unica forma de saber si un registro esta bloqueado o no es intentar actualizarlo y ver si se genera un error, lo cual no es nada practico.

Que cosas podemos hacer para minimizar el alcance de un bloqueo y el tiempo que este permanece activo?

a) Utilizar transacciones atomicas que duren lo menos posible.  En especial, asegurarnos que no se intoducen wait-states en el medio de una transaccion, como por ejemplo mostrar un dialogo de confirmacion al usuario luyego de haber iniciado una transaccion.

b) Intentar siempre que sea posible el primary key al hacer un UPDATE o DELETE, ya que esto minimiza los bloqueos por pagina

c) Asegurarnos que existe un indice para todas las columnas mencionads en el WHERE de un UPDATE o DELETE, y evitar el uso de expresiones compuestas en los WHERE, tales como WHERE campo1 + campo2 = valor.

d) Utilizar el table-hint WITH (ROWLOCK) para indicar a la BD que force el uso de bloqueos de registro al hacer un UPDATE o DELETE. Esto es util para los casos en los que necesitamos actualizar o eliminar VARIOS registros en lugar de uno especifico, ej:

DELETE FROM clientes WITH (ROWLOCK) WHERE status = 'ANULADO'

Esto garantizara que SQL bloqueara exlusivamente los registros afectados en lugar de usar un bloqueo de pagina (lo que habria bloqueado los registros afectados y todos los demas registros cercanos a ellos).  Sin embargo, hay que tener en cuenta que el uso de este table-hint no es recomendable para UPDATES o DELETEs que afectaran miles de registros, pues los bloqueos de registro consumen recursos del servidor y desde ese punto de vista es mucho mas eficiente tener unos cuantas decenas de bloqueos de pagina a tener miles de bloqueos de registro.

Saludos

Victor Espina

TurbiSoft

unread,
Oct 12, 2011, 7:54:04 AM10/12/11
to Comunidad de Visual Foxpro en Español
Wao !!!, Excelente explicacion y aporte para lo que no somos tan
versados en la materia.

Felicitaciones Victor, pondre esas sugerencias y conocimiento en
practica.

Luis Alberto Turbi
Rep. Dominicana

Osornino (Chile)

unread,
Oct 12, 2011, 10:18:44 AM10/12/11
to Comunidad de Visual Foxpro en Español
Victor, realmente excelente.
Muchas Gracias por lo completa y realmente util respuesta.

Nuevamente muchas gracias.

Victor Espina

unread,
Oct 12, 2011, 10:25:58 AM10/12/11
to publice...@googlegroups.com
Gracias a todos por sus comentarios. Si quieren profundizar mas en el tema de los bloqueos en SQL Server, les recomiendo esta serie de articulos:



Saludos

Victor Espina

Easy Gestion

unread,
Oct 13, 2011, 6:57:28 PM10/13/11
to publice...@googlegroups.com
Hola Victor, una consulta, tal vez puedas ayudarme, con MySQL sucede lo mismo?, gracias por leer mi consulta.

Saludos

Gabriel

Victor Espina

unread,
Oct 13, 2011, 7:57:26 PM10/13/11
to publice...@googlegroups.com
No tengo experiencia con MySQL, pero debe ser muy parecido. Donde si puede diferir bastante es con el tema de los table hints, ya que esto es algo bien particular de SQL Server, asi que no te sabria decir si MySQL tiene algo parecido.

Saludos

Victor Espina

Easy Gestion

unread,
Oct 14, 2011, 7:16:15 PM10/14/11
to publice...@googlegroups.com
Mil gracias por responder.

Saludos

Gabriel
Reply all
Reply to author
Forward
0 new messages