Bloquear la lectura de un registro. MS-SQL2005 SP2

15/12/2008 - 17:01 por Rafael Cano | Informe spam
Hola a todos:

¿Cómo puedo bloquear dentro de una transacción un registro?
Creía que con esto se podía:

SELECT * FROM MiEsquema.MiTabla
WITH (XLOCK, ROWLOCK) WHERE PK_KEY = Valor;

Pero me bloquea la lectura de la tabla por completo

Quiero que funcione esta instruccion
SELECT * FROM MiEsquema.MiTabla
WHERE PK_KEY != Valor;

Quiero que se quede esperando la select en el caso de que la selección
de datos coja el id bloqueado.
SELECT * FROM MiEsquema.MiTabla

Al ser posible quiero que la solución sea independiente a como esté
configurado el comando SET TRANSACTION ISOLATION LEVEL la base de datos
está en READ COMMITTED.



Salu2 Rafael Cano
rcanop(arroba)yahoo.es
Jaén - España
Villamartín - Cádiz - España

Preguntas similare

Leer las respuestas

#1 Gustavo Larriera (MVP)
15/12/2008 - 19:47 | Informe spam
Muestre el CREATE TABLE y los CREATE INDEX que usted tiene.

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



"Rafael Cano" wrote:

Hola a todos:

¿Cómo puedo bloquear dentro de una transacción un registro?
Creía que con esto se podía:

SELECT * FROM MiEsquema.MiTabla
WITH (XLOCK, ROWLOCK) WHERE PK_KEY = Valor;

Pero me bloquea la lectura de la tabla por completo

Quiero que funcione esta instruccion
SELECT * FROM MiEsquema.MiTabla
WHERE PK_KEY != Valor;

Quiero que se quede esperando la select en el caso de que la selección
de datos coja el id bloqueado.
SELECT * FROM MiEsquema.MiTabla

Al ser posible quiero que la solución sea independiente a como esté
configurado el comando SET TRANSACTION ISOLATION LEVEL la base de datos
está en READ COMMITTED.



Salu2 Rafael Cano
rcanop(arroba)yahoo.es
Jaén - España
Villamartín - Cádiz - España

Respuesta Responder a este mensaje
#2 Rubén Garrigós
15/12/2008 - 19:49 | Informe spam
Hola Rafael,

Si lo que quieres es preservar acceso mientras se están haciendo cambios en
un registro esta aproximación puede traerte problemas debido a la
concurrencia pesimista. Lo primero que habría que plantearse es si es
necesario bloquear el registro de esta forma y no se puede optar por una
estrategia optimista. Si aún así prefieres esta aproximación podrías leer el
resto de registros si indicas el hint NOLOCKen la consulta (de perdidos al
rio):

SELECT * FROM MiEsquema.MiTabla WITH (NOLOCK) WHERE PK_KEY != Valor;

En este caso un READPAST no te valdría debido al bloqueo exclusivo que estás
adquiriendo con el XLOCK. ¿El motivo? Imagino que tendrás unas cuantas filas
dentro de la misma página donde está esa fila que adquirio el bloqueo IX
(intent exclusive) a nivel de página. Mientras no se libere no se podrá
adquirir el bloqueo S (shared) que se genera con READ COMMITTED cuando
realizas la consulta. Por ello se te sigue quedando bloqueado debido a que
no puede leer el resto de filas que están en la misma página que tu fila
bloqueada exclusivamente que mantiene el IX a nivel de página. Bueno, no me
lío con este tema, te paso un par de enlaces donde hay abundante información
sobre el funcionamiento de los bloqueos de clave:
http://msdn.microsoft.com/es-es/library/ms191272(SQL.90).aspx y sobre la
tabla de compatibilidades de bloqueos:
http://msdn.microsoft.com/es-es/library/ms186396(SQL.90).aspx

Yo quizás me plantearía usar UPDLOCK en la consulta que te bloquea el
registro que necesitas y en las consultas que quieres que se bloqueen si
acceden a registros bloqueados y usaría entonces el READPAST en la consulta
que quieres que pueda leer el resto de registros.

Un saludo,

Rubén Garrigós
Solid Quality Mentors

"Rafael Cano" wrote in message
news:
Hola a todos:

¿Cómo puedo bloquear dentro de una transacción un registro?
Creía que con esto se podía:

SELECT * FROM MiEsquema.MiTabla
WITH (XLOCK, ROWLOCK) WHERE PK_KEY = Valor;

Pero me bloquea la lectura de la tabla por completo

Quiero que funcione esta instruccion
SELECT * FROM MiEsquema.MiTabla
WHERE PK_KEY != Valor;

Quiero que se quede esperando la select en el caso de que la selección de
datos coja el id bloqueado.
SELECT * FROM MiEsquema.MiTabla

Al ser posible quiero que la solución sea independiente a como esté
configurado el comando SET TRANSACTION ISOLATION LEVEL la base de datos
está en READ COMMITTED.



Salu2 Rafael Cano
rcanop(arroba)yahoo.es
Jaén - España
Villamartín - Cádiz - España
Respuesta Responder a este mensaje
#3 Rafael Cano
15/12/2008 - 20:19 | Informe spam
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id =
OBJECT_ID(N'[Gestasa].[CONTADOR]') AND type in (N'U'))
BEGIN
CREATE TABLE [Gestasa].[CONTADOR](
[TABLA] [char](10) COLLATE Modern_Spanish_CI_AI NOT NULL,
[ID] [int] NOT NULL,
CONSTRAINT [PKCONTADOR] PRIMARY KEY NONCLUSTERED
(
[TABLA] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =
OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [INDICES]
) ON [DATOS]
END
GO

SET ANSI_PADDING ON
GO

IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id =
OBJECT_ID(N'[DF__CONTADOR__ID__19DFD96B]') AND type = 'D')
BEGIN
ALTER TABLE [Gestasa].[CONTADOR] ADD DEFAULT ((0)) FOR [ID]
END

GO



Gustavo Larriera (MVP) escribió:
Muestre el CREATE TABLE y los CREATE INDEX que usted tiene.




Salu2 Rafael Cano
rcanop(arroba)yahoo.es
Jaén - España
Villamartín - Cádiz - España
Respuesta Responder a este mensaje
#4 Rafael Cano
15/12/2008 - 20:38 | Informe spam
Perdón si funciona bien, el tema es que estaba haciendo las pruebas
malamente, en vez de hacer:
SELECT * FROM MiEsquema.MiTabla
WITH (XLOCK, ROWLOCK) WHERE PK_KEY = Valor;
GO
SELECT * FROM MiEsquema.MiTabla
WHERE PK_KEY != Valor;
GO

Desde la consola de MSSQL Management Studio, lo estaba haciendo, sin el
el GO por lo que me tomaba todo como un solo lote y me daba la sensación
de que la primera consulta no se hacía.

Gracias a todos por su tiempo.

Rafael Cano escribió:
Hola a todos:

¿Cómo puedo bloquear dentro de una transacción un registro?
Creía que con esto se podía:

SELECT * FROM MiEsquema.MiTabla
WITH (XLOCK, ROWLOCK) WHERE PK_KEY = Valor;

Pero me bloquea la lectura de la tabla por completo

Quiero que funcione esta instruccion
SELECT * FROM MiEsquema.MiTabla
WHERE PK_KEY != Valor;

Quiero que se quede esperando la select en el caso de que la selección
de datos coja el id bloqueado.
SELECT * FROM MiEsquema.MiTabla

Al ser posible quiero que la solución sea independiente a como esté
configurado el comando SET TRANSACTION ISOLATION LEVEL la base de datos
está en READ COMMITTED.






Salu2 Rafael Cano
rcanop(arroba)yahoo.es
Jaén - España
Villamartín - Cádiz - España
Respuesta Responder a este mensaje
#5 Rafael Cano
15/12/2008 - 20:42 | Informe spam
Perdón si funciona bien, el tema es que estaba haciendo las pruebas
malamente, en vez de hacer:
SELECT * FROM MiEsquema.MiTabla
WHERE PK_KEY != Valor; -- Esto debe dar resultado
GO
SELECT * FROM MiEsquema.MiTabla -- Esto debe quedar en espera de término
transaccion
GO

Desde la consola de MSSQL Management Studio, lo estaba haciendo, sin el
el GO por lo que me tomaba todo como un solo lote y me daba la sensación
de que la primera consulta se quedaba bloqueada cuando en verdad era la
segunda.

Gracias a todos por su tiempo.

Rafael Cano escribió:
Hola a todos:

¿Cómo puedo bloquear dentro de una transacción un registro?
Creía que con esto se podía:

SELECT * FROM MiEsquema.MiTabla
WITH (XLOCK, ROWLOCK) WHERE PK_KEY = Valor;

Pero me bloquea la lectura de la tabla por completo

Quiero que funcione esta instruccion
SELECT * FROM MiEsquema.MiTabla
WHERE PK_KEY != Valor;

Quiero que se quede esperando la select en el caso de que la selección
de datos coja el id bloqueado.
SELECT * FROM MiEsquema.MiTabla

Al ser posible quiero que la solución sea independiente a como esté
configurado el comando SET TRANSACTION ISOLATION LEVEL la base de datos
está en READ COMMITTED.






Salu2 Rafael Cano
rcanop(arroba)yahoo.es
Jaén - España
Villamartín - Cádiz - España
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida