SQL Server 2008 almacenado Proc que se ejecuta simultáneamente los retrasos
Pregunta
Tengo un problema en el que parece que al ejecutar el mismo procedimiento almacenado al mismo tiempo desde dos instancias diferentes de la misma aplicación, está en tiempo, y me preguntaba si había algo que pudiera hacer para resolverlo.
Creo que el problema está en la forma en que SQL Server 2008 se maneja, bloqueando filas y ejecutando las SP ... cosas de las que realmente no sé mucho. La aplicación usa ADODB.Command
para ejecutar el sp.
Tengo un vb6 exe (App.exe
), ejecutándose en el servidor varias veces. Esta aplicación llama a un proceso almacenado en la base de datos que devuelve el siguiente número de secuencia para esa aplicación. Este campo de número de secuencia es único para la instancia de la aplicación: hay 1 fila en una tabla (tbl_SequenceNos
) para cada instancia de la aplicación en ejecución.
Entonces, por ejemplo, digamos que tenemos en ejecución: App[a].exe
y App[b].exe
tblSequenceNos
parece:
iAppNo| iNextSequenceNo
a | 1234
b | 4567
El procedimiento almacenado para obtener el siguiente número de secuencia es relativamente simple:
CREATE PROEDURE GetNextSequenceNo (@AppNo varchar(1), @NextSequenceNo int output)
AS
BEGIN
DECLARE @TempSequenceNo int
SELECT @NextSequenceNo = iNextSequenceNo
FROM tblSequenceNos
WHERE iAppNo = @AppNo
@NextSequenceNo = @NextSequenceNo + 1
UPDATE tblSequenceNos
SET iNextSequenceNo = @NextSequenceNo
WHERE iAppNo = @AppNo
END
Cuando ambos App[a].exe
y App[b].exe
Intente ejecutar este procedimiento para obtener su NextSequenceNo
Valor, están colgando durante unos 30 segundos (¿Tiempo de espera de ADO?).
Debido a que cada aplicación nunca mira la fila de los demás, pensé que esto funcionaría simultáneamente sin especificar un bloqueo especial. ¿Hay algo que este olvidando? Pensé que tal vez necesito especificar para bloquear la fila solamente, no toda la tabla o página. - No sé qué hace SQL2008 por defecto.
¡Cualquier ayuda es muy apreciada! Gracias de antemano Andrew
Solución
Su procedimiento no es seguro de subprocesos y producirá resultados incorrectos porque entre los hilos Select y la actualización de múltiples podría obtener la misma secuencia NR.
CREATE PROCEDURE GetNextSequenceNo (@AppNo varchar(1), @NextSequenceNo int output)
AS
DECLARE @var table(seq int);
UPDATE tblSequenceNos
SET iNextSequenceNo = @NextSequenceNo + 1
OUTPUT inserted.iNextSequenceNo INTO @var;
WHERE iAppNo = @AppNo
select @NextSequenceNo = seq from @var
GO
También asegúrese de que su columna IAPPNO esté indexada. (Esto significa solo un índice en esta columna o un índice donde este campo es el primer campo en su índice)