2012-02-16 10 views
17

Hay muchas preguntas sobre CÓMO usar Transacciones. Lo que quiero saber es CUANDO? ¿Bajo que circunstancias? ¿Qué tipos de consultas? ¿Pueden los bloques Try-Catch ser suficientes en su lugar? Etc ...Cuándo usar Transacciones en SQL Server

He diseñado una base de datos con ~ 20 tablas y ~ 20 procedimientos almacenados. Actualmente, ninguno de mis SP usa una transacción, pero hay numerosos bloques Try-Catch en todo momento. La razón es porque cada vez que traté de envolverlos en una transacción, el SP dejaba de funcionar y yo terminaba con datos faltantes y peores que si hubiera usado Trans.

Así que de nuevo ...

  1. Cuando es el momento apropiado para utilizar una transacción?
  2. Como una pregunta de seguimiento, si los utilizo, ¿cómo puedo usarlos de manera que SOLO evite que otros SP accedan a los mismos datos al mismo tiempo para evitar daños en lugar de causar mis SP? para no funcionar en absoluto?

He aquí una pequeña muestra de SP que escribí para cambiar el nombre de un producto:

CREATE PROCEDURE spRenameProduct 
    @pKey int = NULL, 
    @pName varchar(50) 
AS 
BEGIN 
    BEGIN TRY 
     IF LTRIM(RTRIM(@pName)) = '' SET @pName = NULL 
     IF NOT @pKey IS NULL AND NOT @pName IS NULL BEGIN 
      declare @pKeyExisting int = (select MIN(ID) from rProduct where Product like @pName and not ID = @pKey) 
      IF @pKeyExisting is null BEGIN 
       update rProduct set IsValid = 1, Product = @pName where ID = @pKey 
      END ELSE BEGIN 
       update Request set ProductID = @pKeyExisting where ProductID = @pKey 
       update StatusReport set ProductID = @pKeyExisting where ProductID = @pKey 
       delete from rProduct where ID = @pKey 
      END 
     END 
    END TRY BEGIN CATCH END CATCH 
END 

Ahora lo que si dos personas estaban usando esto en el mismo momento? Realmente no quiero, ni tengo tiempo (por desgracia), para llegar a ser elegante. BESO. es mejor en este caso. :)

+0

Está mezclando el nivel de aislamiento con la transacción. Con el aislamiento, puede bloquear otras actualizaciones por la duración de esa declaración única. Si necesita un conjunto de actualizaciones para suceed o fail como conjunto, las envuelve en una transacción. Si desea que las dos actualizaciones y una eliminación permanezcan sincronizadas, eso es lo que puede hacer una transacción. – Paparazzi

+0

@BalamBalam Entonces, en otras palabras, puede ser lógico ajustar solo las dos actualizaciones y una eliminación en una transacción, pero siempre solo envolviendo SP completos no tiene mucho sentido, supongo. Aun así, creo que las trans a veces pueden ser demasiado engorrosas para trabajar porque los desarrolladores a veces cometen errores. No me gustaría que la aplicación falle solo por una excepción inofensiva como referencia nula o algo así. ¿Alguna palabra de sabiduría? Todavía nuevo en esto :) – Chiramisu

+0

No sé cómo decirlo de forma más clara. Si necesita que el conjunto falle o que tenga éxito como un todo, envuélvalo en una transacción. El ejemplo clásico es la transferencia de dinero de una cuenta de cheques a una de ahorro: si el depósito falla, entonces quiero que la retirada falle. Si los datos no están sincronizados debido a un error del desarrollador está bien, entonces no use transacciones. – Paparazzi

Respuesta

27

Utiliza transacciones cuando el conjunto de operaciones de la base de datos que está realizando debe ser atomic.

Es decir, todos deben tener éxito o error. Nada en el medio.

Las transacciones se deben utilizar para garantizar que la base de datos siempre se encuentre en un estado coherente.

En general, a menos que haya una buena razón para no usarlos (proceso de larga ejecución, por ejemplo), úselos. Ver this blog post para más detalles.


Try/Catch bloques tienen nada que ver con las transacciones - que se utilizan para el manejo de excepciones. Los dos conceptos no están relacionados y no son reemplazos entre sí.

+1

+1 y ** NO ** - un bloque 'try ... catch' es ** NO ** un reemplazo suficiente para una transacción .... –

+0

@marc_s - Absolutamente. Se agregaron párrafos sobre eso ahora ... – Oded

+0

@Oded Lo que espero obtener es algunas cosas que puedo buscar como desarrollador y que pueden incitarme a considerar el uso de una transacción. Por ejemplo, "Hmmm, hay una declaración de 'actualización' allí, tal vez debería usar una transacción". o "Eso es solo un 'seleccionar', así que obviamente no necesito una transacción". etc. ¿Qué tal 'borrar'? ¿Las operaciones básicas de CRUD u otras que pueden indicar la necesidad de una trans? – Chiramisu

0

La respuesta común es que las transacciones permiten que las operaciones de la base de datos sean atómicas. La confusión está en lo que esto significa. No se trata de las operaciones particulares involucradas, ya sean SELECT, UPDATE, DELETE, etc. Se trata del significado semántico de los datos en sí. Desde el punto de vista de las operaciones, desde abajo hacia arriba, decimos que, como grupo, son atómicas. Pero, desde el nivel abstracto, mirando de arriba hacia abajo, decimos que tenemos conservación de la información.

Un ejemplo fácil sería si tuviera 2 cuentas y no quisiera que se creara dinero ni se destruyera en la transferencia entre ellas. Otro ejemplo más sutil sería si tuviera un grupo de datos que necesitara crearse o destruirse como un grupo. En otras palabras, tener información parcial no tiene sentido. Supongo que un ejemplo podría ser si tuvieras un usuario y siempre quisieras garantizar que tuvieran un nombre y un apellido. No es un nombre parcial.

Dicho esto, la gente presenta frases y reglas generales para expresar qué significa atómica, como "las operaciones necesitan todas para tener éxito o fallar". Además, las personas tienden a notar patrones, como que un SELECT no necesitaría una transacción.

Cuestiones relacionadas