Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Bloqueo de registros en SQL Server 2008

1,696 views
Skip to first unread message

José Antonio Muñoz

unread,
Jan 30, 2009, 4:12:43 AM1/30/09
to
Hola al grupo,

Estoy desarrollando una aplicación con SQL Server para gestionar 5 puestos
en red. Estoy intentando analizar como se bloquean filas individuales y
también en grupo. Para bloquear filas individuales estoy utilizando las
sugerencias de consulta WITH (ROWLOCK, HOLDLOCK, UPDLOCK) en la cláusula
FROM de una consulta y parece ser que funciona correctamente, al intentar
abrir un recordset en una transacción bloquea la fila correspondiente a la
consulta y el resto de usuarios no pueden abrir en otra transacción la misma
fila. Sin embargo cuando intento ejecutar una consulta que me devuelve
varias filas me bloquea toda la tabla y no las filas individuales.

¿Como puedo solucionar este problema?

Saludos,
José Antonio Muñoz.

Gustavo Larriera (MVP)

unread,
Jan 30, 2009, 9:35:18 AM1/30/09
to
Seré curioso: Por qué desea usted indicarle a SQL Server lo qué cosas deberá
lockear, en vez de permitirle que lo haga en forma automática acorde al
SERIALIZATION LEVEL que se haya establecido?

--
Gustavo Larriera, Microsoft MVP
http://www.linkedin.com/in/gustavolarriera
--
Este mensaje se proporciona tal como es, sin garantías de ninguna clase.

José Antonio Muñoz

unread,
Jan 30, 2009, 11:36:58 AM1/30/09
to
¿Cómo puedo establecer el SERIALIZATION LEVEL para automatizar el bloqueo de
registros y de tablas?

saludos,
José Antonio Muñoz

"Gustavo Larriera (MVP)" <GustavoLa...@discussions.microsoft.com>
escribió en el mensaje de noticias
news:DA5B3225-8EA5-4EE1...@microsoft.com...

Gustavo Larriera (MVP)

unread,
Jan 30, 2009, 11:50:07 AM1/30/09
to
Espero que estos artículos le sean útiles. El primero es algo viejo pero las
ideas aún sirven. El segundo apunta al BOL donde se explica cómo se usa SET
TRANSACTION ISOLATION para configurar el nivel de aislamiento que desee.

Lo habitual es usar el nivel READ COMMITTED o el nivel REPEATABLE READ. Pero
cuál usar depende de lo que sus transacciones necesiten hacer.

Locking in Microsoft SQL Server
http://www.mssqlcity.com/Articles/Adm/SQL70Locks.htm


SET TRANSACTION ISOLATION LEVEL (Transact-SQL)
http://msdn.microsoft.com/en-us/library/ms173763.aspx

José Antonio Muñoz

unread,
Feb 2, 2009, 4:44:52 AM2/2/09
to
Hola Gustavo,

He mirado los artículos que me has enviado y son interesantes, muchas
gracias por ello, sin embargo no resulve mi problema. Te explico:

Yo tengo una tabla que tiene un campo que se repite según unas determinadas
condiciones. Si un usuario necesita modificar los registros cuyo valor de
ese campo sea 1 (puede haber varios registros) primero hago un SELECT para
ver que registros que son y uno por uno voy modificando con la instrucción
UPDATE. Otro usuario puede modicar otros registros con otro valor de campo y
así sucesivamente con muchos usuarios. Yo necesito bloquear todos los
registros seleccionados por el usuario X para que nadie pueda modificar (ni
siquiera ver con un SELECT) esos registros sin embargo he probado con los
diferentes niveles de aislamiento y los diferentes Hits de bloqueos pero no
me funciona ya que o bloquea todos los registros de la tabla y por tanto los
demas usuarios no pueden hacer su SELECT correspondiente para modificar o no
me bloquea ningún registro y por ello todo el mundo ve los registros incluso
los bloqueados.

NOTA: Solo cuando el campo correspondiente sea clave y no se repita el
bloqueo si funciona correctamente, es decir, que puedo hacer un SELECT cuyo
valor sea 1 y solo me recupera un registro. Otro usuario intenta hacer
SELECT a ese registro y no puede ya que da un error de bloqueo. Pero si hace
un SELECT de otro registro, por ejemplo, el 2 y si puede.

Saludos,
José Antonio Muñoz.

"Gustavo Larriera (MVP)" <GustavoLa...@discussions.microsoft.com>
escribió en el mensaje de noticias

news:6E177995-CE8C-4935...@microsoft.com...

Gustavo Larriera (MVP)

unread,
Feb 2, 2009, 7:33:00 AM2/2/09
to
Hola José Antonio Muñoz,

"José Antonio Muñoz" wrote:

> Yo tengo una tabla que tiene un campo que se repite según unas determinadas
> condiciones. Si un usuario necesita modificar los registros cuyo valor de
> ese campo sea 1 (puede haber varios registros) primero hago un SELECT para
> ver que registros que son y uno por uno voy modificando con la instrucción
> UPDATE.

Cuando usted dice "uno por uno voy modificando" se refiere a que usa un
cursor? O cómo es que usted hace esa modificación fila por fila?

> NOTA: Solo cuando el campo correspondiente sea clave y no se repita el
> bloqueo si funciona correctamente, es decir, que puedo hacer un SELECT cuyo
> valor sea 1 y solo me recupera un registro. Otro usuario intenta hacer
> SELECT a ese registro y no puede ya que da un error de bloqueo. Pero si hace
> un SELECT de otro registro, por ejemplo, el 2 y si puede.
>

Puede usted mostrar la estructura de la tabla y los índices que hay creados
para ella?

Saludos
~gux

Jose Mariano Alvarez

unread,
Feb 2, 2009, 7:41:15 AM2/2/09
to
No me queda claro el motivo de bloquear la visibilidad de registros mientras
otro usuario los esta viendo.
Coincido con Gux, por que no utilizas un update masivo en lugar de un
registro por vez?

La tabla tiene PK?
Si es asi, usted no puede tener inconvenientes ya que un update por PK solo
deberia bloquear el registro que actualiza.

--

Saludos

------------------------
Ing. Jose Mariano Alvarez
SQLTotal Consulting
Mi.Correo.es.j0s...@gmail.c0m.Corregirl0
(Cambia los ceros por O y saca lo que sobra)

Este mensaje se proporciona tal como es, SIN GARANTIAS de ninguna clase. Por
favor tratar de indicar la versión de SQL y Service Pack. La inclusión de
(CREATE, INSERTS, etc.) para poder reproducir el problema también ayuda.


"Gustavo Larriera (MVP)" <GustavoLa...@discussions.microsoft.com>
wrote in message news:D5745543-A187-444C...@microsoft.com...

Jesús

unread,
Feb 2, 2009, 9:02:33 AM2/2/09
to

"José Antonio Muñoz" <josean...@hotmail.com> escribió en el mensaje de
noticias news:%23Bf%23zrRhJ...@TK2MSFTNGP02.phx.gbl...

> Hola Gustavo,
>
> He mirado los artículos que me has enviado y son interesantes, muchas
> gracias por ello, sin embargo no resulve mi problema. Te explico:
>
> Yo tengo una tabla que tiene un campo que se repite según unas
> determinadas condiciones. Si un usuario necesita modificar los registros
> cuyo valor de ese campo sea 1 (puede haber varios registros) primero hago
> un SELECT para ver que registros que son y uno por uno voy modificando con
> la instrucción UPDATE. Otro usuario puede modicar otros registros con otro
> valor de campo y así sucesivamente con muchos usuarios.

¿Por qué hay que hacer primero un SELECT y luego un UPDATE registro a
registro?

¿No sería mejor hacer sólo esto?

UPDATE Tabla SET Campo = @Valor
WHERE EseCampo = 1

>Yo necesito bloquear todos los registros seleccionados por el usuario X
>para que nadie pueda modificar (ni siquiera ver con un SELECT)

La cuestión es. ¿Por qué?

Uno de los problemas que me encuentro cuando voy a hacer consultorías a los
clientes es que no se puede acceder a la base de datos y realizar
operaciones porque las cosas están bloqueadas. ¿Y tú quieres bloquear?

Esa manera de bloquear las cosas que estás intentando se llama "bloqueo
pesimista" y hace ya mucho tiempo que está visto que es un enfoque bastante
malo. Hay otras maneras de controlar la concurrencia que bloquear y
bloquear, como por ejemplo el "bloqueo optimista".

José Antonio Muñoz

unread,
Feb 2, 2009, 12:06:04 PM2/2/09
to
El proceso es bastante complejo como para explicarlo aquí en el foro, se
trata de una aplicación donde a través de una tabla principal que se compone
de muchos campos (más de 100 campos) y muchos de estos campos se actualizan
a partir de muchas tablas maestras (en total pueden existir más de 50
tablas). El usuario necesita tener bloqueado un grupo determinado de
registros que a su vez está modificando otras tablas en un orden
determinado, claro si hay que actualizar muchos datos con fórmulas,
procesos, validaciones, etc., y, además, se requieren varios formularios de
entrada de datos es por lo que es necesario el bloqueo, para que otro
usuario no pueda tocar ni ver esos datos mientras están en el proceso que he
explicado anteriormente. Simplemente es así, no hay otra forma, ya que
durante la actualización de estos registros se generan datos intermedios que
reflejarían un estado que no se correspondería con la realidad cuando el
otro usuario intenta consultar esos mismos datos en otro terminal.

No sé si me he explicado bien. De todas formas hoy mismo, probando, he
generado un índice "noclustered" y no "único" a partir del campo en cuestión
y "vualá" el problema se ha solucionado de golpe. Parece ser que en el
bloqueo de registros de SQL server intervienen los índices.

Muchas gracias por vuestra colaboración.

Saludos,
José Antonio Muñoz.

"Gustavo Larriera (MVP)" <GustavoLa...@discussions.microsoft.com>
escribió en el mensaje de noticias

news:D5745543-A187-444C...@microsoft.com...

Jesús

unread,
Feb 2, 2009, 3:32:42 PM2/2/09
to
Realmente es una mala práctica mantener bloqueados recursos dejando al
usuario el control de cuando se liberan dichos recursos.


"José Antonio Muñoz" <josean...@hotmail.com> escribió en el mensaje de
noticias news:%23TsqXiV...@TK2MSFTNGP06.phx.gbl...


> El proceso es bastante complejo como para explicarlo aquí en el foro, se
> trata de una aplicación donde a través de una tabla principal que se
> compone de muchos campos (más de 100 campos) y muchos de estos campos se
> actualizan a partir de muchas tablas maestras (en total pueden existir más
> de 50 tablas). El usuario necesita tener bloqueado un grupo determinado de
> registros que a su vez está modificando otras tablas en un orden
> determinado, claro si hay que actualizar muchos datos con fórmulas,
> procesos, validaciones, etc., y, además, se requieren varios formularios
> de entrada de datos es por lo que es necesario el bloqueo, para que otro
> usuario no pueda tocar ni ver esos datos mientras están en el proceso que
> he explicado anteriormente. Simplemente es así, no hay otra forma, ya que
> durante la actualización de estos registros se generan datos intermedios
> que reflejarían un estado que no se correspondería con la realidad cuando
> el otro usuario intenta consultar esos mismos datos en otro terminal.
>

Sí existe otra forma. Hasta que no se haya finalizado el proceso no haces
ninguna modificación en la base de datos. Toda la información intermedia la
vas almacenado en otro sitio como por ejemplo en memoria, en tablas
intermedias, o donde quieras. Cuando tengas toda la información necesaria
para realizar el proceso completo empiezas una transacción, haces todas las
modificaciones a la base de datos que tengas que hacer y confirmas la
transacción. De esta manera la duración de los bloqueos no está bajo el
control del usuario, durará lo que tarde en ejecutarse las intrucciones
SQL..

Carlos M. Calvelo

unread,
Feb 2, 2009, 5:15:47 PM2/2/09
to
Hola Jesús, José Antonio,

On 2 feb, 21:32, Jesús <sqlranger.quitae...@mvps.org.nospam> wrote:
> Realmente es una mala práctica mantener bloqueados recursos dejando al
> usuario el control de cuando se liberan dichos recursos.

Cierto. Muy mala práctica.
No debe haber la más mínima interacción con el usuario dentro
de una transacción.


>
> "José Antonio Muñoz" <joseantoni...@hotmail.com> escribió en el mensaje de
> noticiasnews:%23TsqXiV...@TK2MSFTNGP06.phx.gbl...


>
> > El proceso es bastante complejo como para explicarlo aquí en el foro, se
> > trata de una aplicación donde a través de una tabla principal que se
> > compone de muchos campos (más de 100 campos) y muchos de estos campos se
> > actualizan a partir de muchas tablas maestras (en total pueden existir más
> > de 50 tablas). El usuario necesita tener bloqueado un grupo determinado de
> > registros que a su vez está modificando otras tablas en un orden
> > determinado, claro si hay que actualizar muchos datos con fórmulas,
> > procesos, validaciones, etc., y, además, se requieren varios formularios
> > de entrada de datos es por lo que es necesario el bloqueo, para que otro
> > usuario no pueda tocar ni ver esos datos mientras están en el proceso que
> > he explicado anteriormente. Simplemente es así, no hay otra forma, ya que
> > durante la actualización de estos registros se generan datos intermedios
> > que reflejarían un estado que no se correspondería con la realidad cuando
> > el otro usuario intenta consultar esos mismos datos en otro terminal.
>
> Sí existe otra forma. Hasta que no se haya finalizado el proceso no haces
> ninguna modificación en la base de datos. Toda la información intermedia la
> vas almacenado en otro sitio como por ejemplo en memoria, en tablas
> intermedias, o donde quieras. Cuando tengas toda la información necesaria
> para realizar el proceso completo empiezas una transacción, haces todas las
> modificaciones a la base de datos que tengas que hacer y confirmas la
> transacción. De esta manera la duración de los bloqueos no está bajo el
> control del usuario, durará lo que tarde en ejecutarse las intrucciones
> SQL..
>


Yo presiento que el problema de José Antonio es más complejo que
eso. Los datos de entrada (input) de ese proceso no vienen solo
de la aplicación sino también de la base de datos misma. Cualquier
cambio en esos datos, por ejemplo a causa de acciones de otros
usuarios, puede invalidar el proceso. Y ese proceso no equivale
a una transación, sino a una serie de transaciones.
Me explico:

A mi me dá la impresión que el problema que tiene José Antonio es
de análisis de ese proceso y de (re)diseño de la base de datos para
poder acomodarlo. Estoy pensando en que los registros implicados
(entidades o como quiera llamarsele) pueden tener que pasar por una
serie de estados donde cada paso de un estado a otro de los
siguientes posibles sí puede considerarse como una transacción en
el sentido que se está hablando aquí. Todas esas entidades pueden
estar en cualquier estado en cualquier momento y la base de datos
estar en un estado consistente en cuanto a integridad de datos. Lo
que está o no permitido hacer con esas entidades dependería
naturalmente del estado en que se encuentren (restricciones de
transición). También es posible que sea necesario que ese proceso
'lleve consigo' todos los datos de entrada necesarios y que
pertenecen al proceso (una copia de los originales al inicio del
proceso).

Solo unas ideas generales por lo que presiento 'entre líneas' en
lo que describe José Antonio. Pero puede que mi intuición me engañe.

Saludos,
Carlos

Jesús

unread,
Feb 2, 2009, 6:36:59 PM2/2/09
to
En caso de que los cambios en los datos invalide el proceso, tenemos dos
opciones:

1) Detectar ese cambio a la hora de realizar la transacción.

Me refiero al estilo de detecciones de conflictos de concurrencia usando por
ejemplo técnicas basadas en columnas timestamp. Si se detecta que ha
ocurrido un cambio, se lanza un error y hay que empezar de nuevo. Si la
posibilidad o frecuencia de que se produzca un cambio que invalide el
proceso es lo suficientemente pequeña como para considerarla despreciable, o
al menos lo suficientemente pequeña como para "poder vivir con ella", Esta
opción es adecuada.


2) Implementar un mecanismo de check-out y check-in.

Antes comenzar la operación, el usuario hace check-out sobre el objeto
(entidad, conjunto de entidades, filas o lo que sea). La aplicación
implementa la lógica que impide a otros usuarios modificar el objeto sin
haber hecho primero un check-out, pero no impide ver el objeto. Además la
aplicación impide que dos usuarios puedan hacer check-out sobre el mismo
objeto.

Una vez hecho el check out, la aplicación recopila toda la información
necesaria para realizar el proceso completo, como dije antes la información
intermedia se puede guardar donde sea.

Hasta el momento no se ha hecho ninguna modificación a la base de datos
excepto lo que supone hacer el checkout.

Cuando tiene toda la información necesaria, el usuario hace check-in. La
aplicación empieza una transacción, hace todas las modificaciones de la base
de datos y confirma la transacción. Entonces otro usuario ya puede hacer
check-out sobre el mismo objeto.


La implementación de check-out y check-in no es muy complicada. Por ejemplo:

/*
En esta tabla tenemos todos los objetos reservables
*/
CREATE TABLE Objects
(
ObjectID int PRIMARY KEY, -- identifica el objeto
UserID int,-- el id del usuario que tiene reservado el objeto
Expiration datetime -- las reservas expiran, no se mantienen para siempre
)
GO

/*
Un objeto puede estar en tres estados:
1) No reservado. UserID y Expiration son nulos. En este estado cualquier
usuario puede hacer checkout, y ninguno puede hacer checkin
2) Reservado. UserID contiene un valor no nulo y Expiration es mayor que
GETDATE(). En este estado sólo el usuario que tiene el objeto reservado
puede hacer check-out (renovar la reserva) o check-in (liberar la reserva).
3) Reserva expirada. UserID contiene un valor no nulo y Expiration es mayor
o igual que GETDATE(). En este estado cualquier usuario puede hacer
check-out incluido el usuario cuya reserva ha expirado. Pero sólo el usuario
que tiene la reserva expirada puede hacer check-in.
*/


/*
Procedimiento que reserva (check-out) o renueva
la reserva de un objeto para un usuario
*/
CREATE PROCEDURE CheckOut
@ObjectID int,
@UserID int
AS
UPDATE Objects
SET
UserID = @UserID,
Expiration = DATEADD(mi, 5, GETDATE()) -- expira en cinco minutos
WHERE
ObjectID = @ObjectID
AND (Expiration < GETDATE() OR Expiration IS NULL OR UserID = @UserID)
IF @@ROWCOUNT = 0
RAISERROR('El objeto ya está reservado por otro usuario', 16, -1)


GO

/*
Procedimiento que libera la reserva de un objeto por parte de un
usuario que lo tenía reservado.
*/
CREATE PROCEDURE CheckIn
@ObjectID int,
@UserID int
AS
UPDATE Objects
SET
UserID = NULL, Expiration = NULL
WHERE
ObjectID = @ObjectID
AND UserID = @UserID
IF @@ROWCOUNT = 0
RAISERROR('
Error al liberar la reserva del objeto por alguna de las siguientes razones:
* Vd. no había reservado el objeto.
* Vd. había reservado el objeto, pero la reserva expiró,
Vd. no la renovó y otro usuario lo reservó', 16, -1)

GO


"Carlos M. Calvelo" <c_ja...@hotmail.com> escribió en el mensaje de
noticias
news:99f9c2de-501c-43e6...@x6g2000pre.googlegroups.com...

Jose Mariano Alvarez

unread,
Feb 2, 2009, 6:54:02 PM2/2/09
to
Jose:

Por que no incluyes banderas o flags en los registros para evitar que lo
accedan en ese momento en lugar de querer bloquear los registros.
Creo que deberias resolver tus problemas desde el punto de vista del diseño
y no forzar a la base de datos a hacer cosas para las cuales el modelo
relacional no esta preparado.
Creo que tarde o temprano vas a encontrar un problema que no vas a poder
resolver si sigues por ese camino, independientemente de la base de datos
relacional que uses.

--

Saludos

------------------------
Ing. Jose Mariano Alvarez
SQLTotal Consulting
Mi.Correo.es.j0s...@gmail.c0m.Corregirl0
(Cambia los ceros por O y saca lo que sobra)

Este mensaje se proporciona tal como es, SIN GARANTIAS de ninguna clase. Por
favor tratar de indicar la versión de SQL y Service Pack. La inclusión de
(CREATE, INSERTS, etc.) para poder reproducir el problema también ayuda.


"José Antonio Muñoz" <josean...@hotmail.com> wrote in message
news:#TsqXiVh...@TK2MSFTNGP06.phx.gbl...

Carlos M. Calvelo

unread,
Feb 2, 2009, 7:44:11 PM2/2/09
to
Hola Jesús,

Parece que no me he explicado bien. No me refería a técnicas para
bloqueo, sino a un análisis del proceso del que habla José Antonio.

Una entidad puede recorrer una serie de estados (piensa en diagramas
de estados) donde el paso de un estado a otro corresponde a una
transacción completa.
Cualquier estado intermedio en el proceso no es un bloqueo sino
que solo expresa donde se encuentra esa entidad en el proceso y,
por medio de restricciones de transición, a que otros estatos
puede pasar. El que una entidad esté en un determinado estado
intermedio en un proceso no bloquea a nadie y puede estar en ese
estado todo el tiempo que sea necesario. Solo dice qué es lo que
se puede hacer con esa entidad, independientemente de quien o
qué haya inicializado el proceso.

Me dió la impresión que quizás José Antonio pueda reconsiderar
ese proceso en esos términos.

Por cierto, buena idea la del check-in / check-out. Como en los
sistemas de control de versiones de código fuente.
Con su 'expiration date' y todo. :) Aunque en control de
concurrencia no debería estar en manos de la(s) aplicación(es).

En todo caso, espero haberme explicado mejor ahora.

Saludos,
Carlos

Jesús

unread,
Feb 2, 2009, 8:26:14 PM2/2/09
to
Hola Carlos,

Mi respuesta venía sobre todo a cuento del párrafo:

"Los datos de entrada (input) de ese proceso no vienen solo
de la aplicación sino también de la base de datos misma. Cualquier
cambio en esos datos, por ejemplo a causa de acciones de otros
usuarios, puede invalidar el proceso"

Sobre todo de la frase "Cualquier cambio en esos datos,...,puede invalidar
el proceso". Creo sinceramente que esa frase describe perfectamente el
problema de José Antonio Muñoz. ¿Por qué si no José Antonio iba a bloquear
las filas sino es para impedir que se modificaran? y ¿Por qué no quiere que
los demás usuarios las vean? Pues creo que porque han sido modificadas, aún
no están confirmadas y respresentan un estado de la base de datos no
consistente desde el pundo de vista del negocio. Creo que la intención de
José Antonio es la de impedir lecturas sucias a los demás usuarios.

Y ante eso pues propongo dos soluciones:

1) Detectar que ha habido cambios e invalidar el proceso
2) Implentar un mecanismo de check-in y check-out, que impida que se
produzca ese cambio en los datos. Como has mencionado, se trata básicamente
de una implementación de bloqueos a nivel de aplicación, lo cual lo
considero mejor alternativa que bloquear recursos en el servidor con control
de su duración por parte del usuario.


Lo de los estados, transiciones de estados y restricciones en las
transiciones de estados, aunque entiendo más o menos lo que quieres decir,
no termino de encajarlo en el contexto. También creo que eso puede ser un
análisis válido que explique por qué "Cualquier cambio en esos
datos,...,puede invalidar el proceso".

Pero pienso que sea lo que sea lo que explique por qué "Cualquier cambio en
esos datos,...,puede invalidar el proceso" las soluciones que he propuesto
funcionarían..

Espero que al final podamos entendernos.

Un saludo:

Jesús López


"Carlos M. Calvelo" <c_ja...@hotmail.com> escribió en el mensaje de
noticias

news:9f676a07-d0d0-4c98...@g3g2000pre.googlegroups.com...

José Antonio Muñoz

unread,
Feb 3, 2009, 3:04:03 AM2/3/09
to
Correcto Jesús, ¡impedir que se efectuen lecturas sucias!. De todas formas
bloquear registros por una aplicación no creo que sea una mala práctica, yo
lo estoy haciendo desde los tiempos del "clipper" y el "basic" y era
entonces una herramienta básica a la hora de programas aplicaciones en red.
Cada herramienta de programación tenía sus métodos para el bloqueo de
registros y de tablas.

En cuanto al proceso del análisis, es posible que volviendo a resiseñar la
aplicación para resolver los problemas de control check-in y check-out sería
una solución pero llevo la aplicación ya muy avanzada para ello y el bloqueo
(ya resuelto) me resuelve el problema.

Gracías por vuestras sugerencias y un saludo,
José Antonio Muñoz.

"Jesús" <sqlranger...@mvps.org.nospam> escribió en el mensaje de
noticias news:%23xNhn5Z...@TK2MSFTNGP03.phx.gbl...

José Antonio Muñoz

unread,
Feb 3, 2009, 3:07:35 AM2/3/09
to
Estoy de acuerdo contigo pero llevo la aplicación muy avanzada y tengo unos
plazos que cumplir y no me puedo plantear ahora rediseñar la aplicación.
Para una próxima aplicación tendré en cuenta vuestros consejos y plantearé
el tema de los bloqueos de otra manera.

Gracias y saludos,
José Antonio Muñoz.

"Jose Mariano Alvarez"
<Mi.Correo.es.j0s...@gmail.c0m.Corregirl0> escribió en el
mensaje de noticias
news:4543C0E2-A62B-4389...@microsoft.com...

Jesús

unread,
Feb 3, 2009, 6:30:39 AM2/3/09
to

"José Antonio Muñoz" <josean...@hotmail.com> escribió en el mensaje de
noticias news:ev0fLYdh...@TK2MSFTNGP05.phx.gbl...

> Correcto Jesús, ¡impedir que se efectuen lecturas sucias!.

No sé si estarás enterado de que a partir de SQL Server 2005 existen dos
nuevos niveles de aislamiento:

* READ COMMITTED SNAPSHOT
* SNAPSHOT

Con estos niveles de aislamiento un usuario podría ver las filas modificadas
y bloqueadas de forma exclusiva por otro usuario que aún no están
confirmadas, sin producirse lecturas sucias. El usuario vería la última
versión confirmada de las filas.

Esto podría ser una solución para permitir ver las filas modificadas sin
incurrir en lecturas sucias. Eso de que "no puedes verlo porque otro usuario
está trabajando con ello" no me gusta demasiado, prefiero darle una vista de
como estaban los datos antes de que empezara a trabajar con ello. Al fin y
al cabo ese "estaban" es en realidad "están", puesto que los cambios aún no
se han confirmado.

> De todas formas bloquear registros por una aplicación no creo que sea una
> mala práctica, yo lo estoy haciendo desde los tiempos del "clipper" y el
> "basic" y era entonces una herramienta básica a la hora de programas
> aplicaciones en red. Cada herramienta de programación tenía sus métodos
> para el bloqueo de registros y de tablas.

¿Te refieres a lo que dijo Carlos o a lo que dije yo?

En cualquier caso lo que es una mala práctica es "que la duración de los
bloqueos de los recursos de SQL Server esté bajo el control de los usuarios"

Por ejemplo esto es mala práctica:

BEGIN TRANSACTION

UPDATE ...

INSERT ...

-- Aquí hay interacción con el usuario.
...
COMMIT

> En cuanto al proceso del análisis, es posible que volviendo a resiseñar la
> aplicación para resolver los problemas de control check-in y check-out
> sería una solución pero llevo la aplicación ya muy avanzada para ello y el
> bloqueo (ya resuelto) me resuelve el problema.
>

¿Y qué me dices de la detección de los conflictos de concurrencia? Es decir,
detectar si ha habido cambios en las filas e invalidar el proceso en tal
caso.
¿Cuantas veces al año se produce tal cosa?
Si los usuarios tienen bien repartido y asignado el trabajo, eso no debería
producirse nunca o casi nunca, y por tanto esto sería la mejor solución.
Los datasets y dataadapters, LINQ to SQL y Entity Framework ya tienen
incorporado mecanismos de detección de conflictos de concurrencia.
¿Introducir estos mecanismos haría que no cumplieras los plazos de entrega?

Jose Mariano Alvarez

unread,
Feb 3, 2009, 7:43:29 AM2/3/09
to
Suerte, luego nos cuentas como te fue.


--

Saludos

------------------------
Ing. Jose Mariano Alvarez
SQLTotal Consulting
Mi.Correo.es.j0s...@gmail.c0m.Corregirl0
(Cambia los ceros por O y saca lo que sobra)

Este mensaje se proporciona tal como es, SIN GARANTIAS de ninguna clase. Por
favor tratar de indicar la versión de SQL y Service Pack. La inclusión de
(CREATE, INSERTS, etc.) para poder reproducir el problema también ayuda.


"José Antonio Muñoz" <josean...@hotmail.com> wrote in message

news:OqFUKadh...@TK2MSFTNGP03.phx.gbl...

0 new messages