SQL Server - CONCURRENCIA EN SQL SERVER 2005

 
Vista:

CONCURRENCIA EN SQL SERVER 2005

Publicado por Byron  (2 intervenciones) el 15/12/2008 21:45:12
Saludos.
Mi problema es el siguiente:

Estoy trabajando sobre una aplicacion sobre powerbuilder utilizabdo sql server 2005 como motor de BD. y requiere generar el secuencial de una tabla utilizando la siguiente sentencia.

SELECT MAX(NoFactura) AS NMAX FROM Facturas
NMAX = NMAX + 1

Bueno esto me habia dado resultados en entornos de trabajo donde el nivel de concurrencia era relativamente no tan exigente, pero ahora tengo un cliente que en ciertas horas llega a tener hasta 30 transacciones por segundo sobre la misma tabla, y obiamente esto esta causando colisiones al momento de generar el secuencial.

Mucho agradecera puedan ayudarme para darle solución a este problemita.


Att

Byron
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:CONCURRENCIA EN SQL SERVER 2005

Publicado por Mau (67 intervenciones) el 16/12/2008 04:11:46
Que tal Byron, no es recomendable usar esa estrategía porque va a generar una cantidad de bloqueos enorme a tu tabla y además, si no estás separando las transacciones es probable que no leas el último número correctamente.

En lugar de hacer eso, te recomiendo crear una tabla auxiliar que contenga un solo campo autonumérico (IDENTITY) y crea un stored procedure (sin transacciones dentro de él) para insertar un registro cada vez que generes una nueva factura. El stored devolverá como un parámetro OUT el nuevo número generado. Esto no te causará problemas de concurrencia.

CREATE TABLE num_facturas(numero INT IDENTITY NOT NULL);
GO

CREATE PROCEDURE siguiente_numero
@numero_factura INT OUT
AS

INSERT INTO num_facturas DEFAULT VALUES

SELECT @numero_factura = @@IDENTITY
GO

Espero haberte ayudado. Saludos!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:CONCURRENCIA EN SQL SERVER 2005

Publicado por Byron (2 intervenciones) el 16/12/2008 18:23:38
GraciasMauricio or tu respuesto solo q ahora la cosa se pone un poco mas complicado, ya que la secuencia de las facturas tiene q ser controlada por SUCURSAL y la solucion q planteas funciona barbaro para el caso de no manejar sucursales, a ver si me ayudas con este problemita???????
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

RE:CONCURRENCIA EN SQL SERVER 2005

Publicado por apis (26 intervenciones) el 16/12/2008 18:33:34
bueno leyendo la pregunta me intereso ya que yo uso algo similar folios para documentos los cuales segun el tipo de documento cambia el folio, y si por ejemplo el usuario se equivoca al estar capturando desea borrar el documento y usar el mismo folio que borro si uso el identity el folio ya no estaria bien
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:CONCURRENCIA EN SQL SERVER 2005

Publicado por Isaias (3308 intervenciones) el 08/01/2009 16:19:15
Muy bien Mau, solo cambiaria el @@IDENTITY, por la funcion IDENT_CURRENT(), ya que el primero, me da el consecutivo de los IDENTITY; mientras la funcion, me da el ultimo identity, de mi transaccion.

Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:CONCURRENCIA EN SQL SERVER 2005

Publicado por Isaias (3308 intervenciones) el 16/12/2008 19:06:28
Respeto mucho el comentario de Mau, que sinceramente no he probado.

Y cierto, como dice apis, el IDENTITY, no fue creado para "equivocaciones" (DELETE, UPDATE), ni para insert's masivos fallidos, ya que se pierde el consecutivo.

Creo que deberias manejar TRANSACCIONES EXPLICITAS

-- Store que sirve como FOLIADOR
CREATE PROCEDURE sPS_ObtieneFolioHost
@iOrigen tinyint = 0,
@iFolioHost int = 0 OUTPUT
AS
BEGIN
SET NOCOUNT ON
BEGIN TRAN MyTran
UPDATE FOLIADOR WITH (ROWLOCK)
SET FOLIO = ISNULL(FOLIO, 0) + 1
SELECT @iFolioHost = FOLIO FROM FOLIADOR ROWLOCK
COMMIT TRAN MyTran
IF @iOrigen = 1
SELECT @iFolioHost
END

Este codigo fue probado con 500 usuarios y nunca hubo duplicidad de folios, adaptalo a tus necesidades.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:CONCURRENCIA EN SQL SERVER 2005

Publicado por Hugo Meneses (2 intervenciones) el 19/03/2013 21:48:51

Muchas Gracias Isaías , me sirvió tu código.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:CONCURRENCIA EN SQL SERVER 2005

Publicado por Hugo Meneses (2 intervenciones) el 19/03/2013 23:49:13

Hay otra opción que no requiere el bloqueo de la tabla y no tiene falla con la concurrencia


USE [DbImportaciones]
GO
/****** Object: StoredProcedure [dbo].[sPS_ObtieneFolioHost] Script Date: 19/03/2013 04:47:21 p.m. ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[sPS_ObtieneFolioHost]
@vIdCompania tinyint = 0,
@Consecutivo int = 0 OUTPUT
AS
/********************************************************************************************************/
/* Creado por: Hugo Meneses */
/* execute sPS_ObtieneFolioHost 24,0 */
/********************************************************************************************************/
-- Store que sirve como FOLIADOR
BEGIN
SET NOCOUNT ON

Declare @FILAS_ACTUALIZADAS TABLE( Consecutivo int )

-- Actualiza Consecutivo
Update DbImportaciones.dbo.TblCompania
Set FolioFactura = FolioFactura + 1
Output INSERTED.FolioFactura INTO @FILAS_ACTUALIZADAS
Where Compania_Id = @vIdCompania

-- Regresa Dato
Select CONVERT(varchar(50),Consecutivo)
From @FILAS_ACTUALIZADAS

END
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar