2011-06-13 14 views
6

Ahora, un compañero de trabajo y yo discutimos sobre el efecto de los bloques no esenciales BEGIN TRAN .... COMMIT TRAN. He escrito acerca de 140 procedimientos almacenados para operaciones simples de inserción-actualización-eliminación y dado que es posible que más adelante tengamos que hacer algunas operaciones adicionales en ellos, ya he incluido los bloques BEGIN TRAN y COMMIT TRAN que podrían ser necesarios como ese :¿Un bloque de transacción reduce el rendimiento en SQL Server?

CREATE PROCEDURE [Users].[Login_Insert] 

     @Username   nvarchar (50) OUTPUT, 
     @Password   char (40), 
     @FullName   nvarchar (150), 
     @LoginTypeId  int 

AS 

SET NOCOUNT ON; 

BEGIN TRY 
BEGIN TRAN 

INSERT [Users].[Login] 
(
     [Username], 
     [Password], 
     [FullName], 
     [LoginTypeId] 
) 
VALUES 
(
     @Username, 
     @Password, 
     @FullName, 
     @LoginTypeId 
) 

COMMIT TRAN 
RETURN 1 
END TRY 

BEGIN CATCH 
ROLLBACK TRAN 

RETURN -1 
END CATCH 

GO 

Ahora, muchas de estas transacciones pueden no ser necesarias. ¿Estos bloques extraños van a afectar el rendimiento de una manera notable? Gracias de antemano.

Respuesta

8

No es suficiente para notarlo.

Es decir, cada TXN estará abierto para un OhNoSecond adicional entre BEGIN TRAN e INSERT. Me impresionaría si alguien pudiera medirlo.

Sin embargo, si usted comenzó TRAN luego provocó la entrada del usuario, las piernas necesitan de ruptura ...

buena idea sin embargo: Puedo hacer esto por lo que todos mis procsos escritura son 100% compatibles, tener el mismo control de errores, se pueden anidar etc

Editar: Después de Remus respuesta, veo que no ligan a mi nido plantilla TXN: Nested stored procedures containing TRY CATCH ROLLBACK pattern? Esto es diferente a Remus en la que siempre se deshace y no tiene puntos de retorno

Editar , una prueba rápida y sucia muestra que es más rápido alrededor de 2/3 del tiempo con la transacción

SET NOCOUNT ON 
SET STATISTICS IO OFF 

DECLARE @date DATETIME2 
DECLARE @noTran INT 
DECLARE @withTran INT 

SET @noTran = 0 
SET @withTran = 0 

DECLARE @t TABLE (ColA INT) 
INSERT @t VALUES (1) 

DECLARE 
    @count INT, 
    @value INT 

SET @count = 1 

WHILE @count < 100 
BEGIN 

    SET @date = GETDATE() 
    UPDATE smalltable SET smalltablename = CASE smalltablename WHEN 'test1' THEN 'test' ELSE 'test2' END WHERE smalltableid = 1 
    SET @noTran = @noTran + DATEDIFF(MICROSECOND, @date, GETDATE()) 

    SET @date = GETDATE() 
    BEGIN TRAN 
    UPDATE smalltable SET smalltablename = CASE smalltablename WHEN 'test1' THEN 'test' ELSE 'test2' END WHERE smalltableid = 1 
    COMMIT TRAN 
    SET @withTran = @withTran + DATEDIFF(MICROSECOND, @date, GETDATE()) 

    SET @count = @count + 1 
END 

SELECT 
    @noTran/1000000. AS Seconds_NoTransaction, 
    @withTran/1000000. AS Seconds_WithTransaction 

Seconds_NoTransaction Seconds_WithTransaction 
2.63200000    2.70400000 
2.16700000    2.12300000 

invirtiendo el orden de la actualización mantiene el mismo comportamiento

+2

Intenté medir esto una vez y no pude. Sin efecto mensurable –

+0

Espero que mi compañero de trabajo llegue a una conclusión al ver esto. Muchas gracias amigo – M2X

+0

[La respuesta aquí dice que es mensurable] (http://stackoverflow.com/questions/3201982/having-transaction-in-all-queries/3273661#3273661) –

5

En el código que envió no habrá ningún efecto medible, pero las transacciones tienen efecto en el rendimiento, que pueden mejorar drásticamente el rendimiento debido a conectarse al ras con confirmación en la agrupación o pueden reducir drásticamente el rendimiento debido a problemas de contención administrados incorrectamente. Pero la conclusión es que cuando las transacciones son necesarias para la corrección no puede saltearse tenerlos. Una vez dicho esto, su plantilla es bastante mala en comparación con las transacciones y los bloques try-catch. La transcation en un bloque catch debe tener una verificación lógica tri-state para valores de retorno XACT_STATE (-1, 0, 1) y manejar adecuadamente las transacciones condenadas. Ver Exception handling and nested transactions para un ejemplo.

Además, nunca debe mezclar el manejo de error try-catch con el manejo de errores de código de retorno. Elija uno y quédese con él, preferiblemente try-catch. En otras palabras, su procedimiento almacenado debe RAISE, no devolver -1. La combinación de excepción con códigos de error hace que su código sea una pesadilla para mantener y llamar correctamente.

+0

Estoy realmente contento de que lo haya mencionado. Gracias por su respuesta – M2X

Cuestiones relacionadas