grabar varios reg simultaneos

18/03/2008 - 12:20 por Hugo Gsell | Informe spam
Utilizo sql server 2000...
Ha esta altura esta pregunta es para matarme...
aunque no muy elegante (por el mecanismo) este código de abajo lo que hace
es grabar un nuevo registro en una tabla.
Dicha tabla tiene un campo clave que es IdMiReg.
Independientemente "de la eficiencia"* la pregunta es si esto esta dentro de
un procedimiento almacenado y ademas esto dentro de un BEGIN TRANSACTION...
si supongamos EN LA EXAGERACION simultaneamente 500 usuarios le dan el enter
y comienzan a ejecutar este SP ¿Funcionaría?, es decir, ¿se generarían
valores DISTINTOS de IdMiReg?
...
BEGIN TRANSACTION
SELECT @NuevoNro = ISNULL(MAX(IdMiReg),0) FROM MiTabla
SET @NuevoNro = @NuevoNro + 1
INSERT INTO MiTabla ( IdBetaAfi,
Campo1
Campo2)
VALUES(
@NuevoNro,
@campo1
@campo2)
SELECT @error = @@ERROR, @NroRegsModificados = @@ROWCOUNT
IF @error != 0
BEGIN
ROLLBACK TRANSACTION
END
ELSE
BEGIN
COMMIT TRANSACTION
END


*me refiero a la eficiencia ya que podríamos tener una tabla con el nro de
siguiente registro... .etc etc... No se discute el mecanismo si si
funcionaría o no como se presenta

Preguntas similare

Leer las respuestas

#1 Maxi Accotto
18/03/2008 - 13:28 | Informe spam
Hola, asi como esta podes tener valores duplicados, fijate este ejemplo
donde es la forma correcta de manejar los numeradores

Tu codigo hace un select y no estas bloqueando con lo cual si hay otra
operacion en el mismo tiempo puede obtener el mismo numero

use northwind
go

create table numeradora (comprobante varchar(30),
ultimo_numero int)
go

insert into numeradora values ('oc',0)

create table oc (numero int,
fecha datetime not null)
go


create proc usp_garbar_oc @fecha datetime
as

declare @proximo_numero int

begin tran

update numeradora
set @proximo_numero = ultimo_numero = ultimo_numero + 1
where comprobante = 'OC'

INSERT INTO OC VALUES (@proximo_numero,@fecha)

commit tran
go

select * from oc

select * from numeradora

exec usp_garbar_oc '20080310'

select * from oc

select * from numeradora

exec usp_garbar_oc '20080311'

select * from oc

select * from numeradora



Microsoft MVP SQLServer
www.sqltotalconsulting.com
-

"Hugo Gsell" escribió en el mensaje de
noticias:
Utilizo sql server 2000...
Ha esta altura esta pregunta es para matarme...
aunque no muy elegante (por el mecanismo) este código de abajo lo que hace
es grabar un nuevo registro en una tabla.
Dicha tabla tiene un campo clave que es IdMiReg.
Independientemente "de la eficiencia"* la pregunta es si esto esta dentro
de un procedimiento almacenado y ademas esto dentro de un BEGIN
TRANSACTION... si supongamos EN LA EXAGERACION simultaneamente 500
usuarios le dan el enter y comienzan a ejecutar este SP ¿Funcionaría?, es
decir, ¿se generarían valores DISTINTOS de IdMiReg?
...
BEGIN TRANSACTION
SELECT @NuevoNro = ISNULL(MAX(IdMiReg),0) FROM MiTabla
SET @NuevoNro = @NuevoNro + 1
INSERT INTO MiTabla ( IdBetaAfi,
Campo1
Campo2)
VALUES(
@NuevoNro,
@campo1
@campo2)
SELECT @error = @@ERROR, @NroRegsModificados = @@ROWCOUNT
IF @error != 0
BEGIN
ROLLBACK TRANSACTION
END
ELSE
BEGIN
COMMIT TRANSACTION
END


*me refiero a la eficiencia ya que podríamos tener una tabla con el nro de
siguiente registro... .etc etc... No se discute el mecanismo si si
funcionaría o no como se presenta

Respuesta Responder a este mensaje
#2 Hugo Gsell
18/03/2008 - 15:03 | Informe spam
Si... me ha servido lo que me pasas
ahora le anexo el problema "real" el tema es que dicho número es un nro de
turno para ser atendido
la cosa es que ademas del nro de turno tengo que asignar una fecha y hora...
y en cada fecha y hora no puede haber mas que 7, porque tengo 7 puestos de
atencion (paralelo) (ojo el 7 en realidad es una cuestión de logica de
negocio.. que puede variar.. asi que supongo que la podría poner como
parametro) como sea... ademas en la lógica de negocio de la aplicacion debo
ver si es un dia habil.. y otros controles mas...
El tema es que si para hacer esos "calculos" (logica de negocio) MI
APLICACION (vb.net) recupera informacion de sql... calcula si la fecha y
hora esta disponible,etc y envia estos datos a grabar en el SP... la
cuestion es que simultaneamente esto es hecho por 500 usuarios... a todos
les podría llegar a calcular la misma fecha y hora.
Lo que estoy haciendo ahora es algo asi
le agregue un campo item..
es decir,
tengo
nroturno, fecha, hora, item y establezco como clave unica este conj de
campos

hago mis calculos (lo que haga en la logica de negocios) recupero info
de tablas... etc... y calculo mi nroturno, fecha, hora e item.
Mando a grabar... si varios usuarios hicieron simultaneamente la operación..
todos pueden llegar a tener el mismo nroturno, fecha, hora e item... por lo
que sql me devolverá un error de índice duplicado.. luego mi aplicación
esperará tiempo aleatorio y volverá a recalcular y enviar a grabar.

HUGO


"Maxi Accotto" escribió en el mensaje
news:
Hola, asi como esta podes tener valores duplicados, fijate este ejemplo
donde es la forma correcta de manejar los numeradores

Tu codigo hace un select y no estas bloqueando con lo cual si hay otra
operacion en el mismo tiempo puede obtener el mismo numero

use northwind
go

create table numeradora (comprobante varchar(30),
ultimo_numero int)
go

insert into numeradora values ('oc',0)

create table oc (numero int,
fecha datetime not null)
go


create proc usp_garbar_oc @fecha datetime
as

declare @proximo_numero int

begin tran

update numeradora
set @proximo_numero = ultimo_numero = ultimo_numero + 1
where comprobante = 'OC'

INSERT INTO OC VALUES (@proximo_numero,@fecha)

commit tran
go

select * from oc

select * from numeradora

exec usp_garbar_oc '20080310'

select * from oc

select * from numeradora

exec usp_garbar_oc '20080311'

select * from oc

select * from numeradora



Microsoft MVP SQLServer
www.sqltotalconsulting.com
-

"Hugo Gsell" escribió en el mensaje de
noticias:
Utilizo sql server 2000...
Ha esta altura esta pregunta es para matarme...
aunque no muy elegante (por el mecanismo) este código de abajo lo que
hace es grabar un nuevo registro en una tabla.
Dicha tabla tiene un campo clave que es IdMiReg.
Independientemente "de la eficiencia"* la pregunta es si esto esta dentro
de un procedimiento almacenado y ademas esto dentro de un BEGIN
TRANSACTION... si supongamos EN LA EXAGERACION simultaneamente 500
usuarios le dan el enter y comienzan a ejecutar este SP ¿Funcionaría?, es
decir, ¿se generarían valores DISTINTOS de IdMiReg?
...
BEGIN TRANSACTION
SELECT @NuevoNro = ISNULL(MAX(IdMiReg),0) FROM MiTabla
SET @NuevoNro = @NuevoNro + 1
INSERT INTO MiTabla ( IdBetaAfi,
Campo1
Campo2)
VALUES(
@NuevoNro,
@campo1
@campo2)
SELECT @error = @@ERROR, @NroRegsModificados = @@ROWCOUNT
IF @error != 0
BEGIN
ROLLBACK TRANSACTION
END
ELSE
BEGIN
COMMIT TRANSACTION
END


*me refiero a la eficiencia ya que podríamos tener una tabla con el nro
de siguiente registro... .etc etc... No se discute el mecanismo si si
funcionaría o no como se presenta

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