Quel est l'intérêt de & # 8220; ROLLBACK TRANSACTION named_transaction & # 8221 ;?
-
06-07-2019 - |
Question
J'ai consulté MSDN dans les TRANSACTION ROLLBACK et < a href = "http://msdn.microsoft.com/en-us/library/ms189336.aspx" rel = "nofollow noreferrer"> transactions d'imbrication . Bien que je voie le point de ROLLBACK TRANSACTION nom_sauvegarde
, je ne comprends pas ROLLBACK TRANSACTION nom_transaction
.
- Cela ne fonctionne que lorsque
nom de transaction
est la transaction la plus externe -
ROLLBACK
annule toujours la totalité de la transaction "pile", sauf dans le cas denom du point de sauvegarde
En gros, à la lecture de la documentation, sauf dans le cas d'un point de sauvegarde, ROLLBACK
annule toutes les transactions (en @@ TRANCOUNT = 0
). La seule différence que je peux voir est cet extrait:
Si une instruction ROLLBACK TRANSACTION nom_ transaction utilisant le nom de la transaction externe est exécutée à n'importe quel niveau d'un ensemble d'imbriqués transactions, toutes les transactions imbriquées sont annulées. Si une instruction ROLLBACK WORK ou ROLLBACK TRANSACTION sans Le paramètre nom_transaction est exécuté à n'importe quel niveau d'un ensemble d'imbriqués transaction, il annule toutes les transactions imbriquées, y compris la transaction la plus externe.
Au vu de la lecture, cela me suggère que, si vous annulez une transaction nommée (qui doit être le nom de la transaction la plus externe), seules les transactions imbriquées seront annulées. Cela donnerait un sens à l'annulation d'une transaction nommée. J'ai donc mis en place un test:
CREATE TABLE #TEMP (id varchar(50))
INSERT INTO #TEMP (id) VALUES ('NO')
SELECT id AS NOTRAN FROM #TEMP
SELECT @@TRANCOUNT AS NOTRAN_TRANCOUNT
BEGIN TRAN OUTERTRAN
INSERT INTO #TEMP (id) VALUES ('OUTER')
SELECT id AS OUTERTRAN FROM #TEMP
SELECT @@TRANCOUNT AS OUTERTRAN_TRANCOUNT
BEGIN TRAN INNERTRAN
INSERT INTO #TEMP (id) VALUES ('INNER')
SELECT id AS INNERTRAN FROM #TEMP
SELECT @@TRANCOUNT AS INNERTRAN_TRANCOUNT
ROLLBACK TRAN OUTERTRAN
IF @@TRANCOUNT > 0 ROLLBACK TRAN
SELECT id AS AFTERROLLBACK FROM #TEMP
SELECT @@TRANCOUNT AS AFTERROLLBACK_TRANCOUNT
DROP TABLE #TEMP
entraîne (toutes les "lignes X affectées" sont supprimées)
NOTRAN
--------------------------------------------------
NO
NOTRAN_TRANCOUNT
----------------
0
OUTERTRAN
--------------------------------------------------
NO
OUTER
OUTERTRAN_TRANCOUNT
-------------------
1
INNERTRAN
--------------------------------------------------
NO
OUTER
INNER
INNERTRAN_TRANCOUNT
-------------------
2
AFTERROLLBACK
--------------------------------------------------
NO
AFTERROLLBACK_TRANCOUNT
-----------------------
0
Notez qu'il n'y a aucune différence dans la sortie lorsque je change
.ROLLBACK TRAN OUTERTRAN
simplement
ROLLBACK TRAN
Alors, quel est l'intérêt de ROLLBACK TRANSACTION transformation_nommée
?
La solution
Les points de sauvegarde sont exactement comme leur nom l'indique: "points de sauvegarde" dans la séquence du journal. La séquence du journal est toujours linéaire. Si vous revenez à un point de sauvegarde, vous annulerez tout votre transaction entre la position actuelle du journal et le point de sauvegarde. Considérez votre exemple:
LSN 1: BEGIN TRAN OUTERTRAN
LSN 2: INSERT INTO ...
LSN 3: BEGIN TRAN INNERTRAN
LSN 4: INSERT INTO ...
LSN 5: ROLLBACK TRAN OUTERTRAN
Au numéro de séquence du journal (LSN) 1, le point de sauvegarde OUTERTRAN est créé. Le premier INSERT crée LSN 2. Ensuite, INNERTRAN crée un point de sauvegarde avec LSN 3. Le second INSERT crée un nouveau LSN, 4. ROLLBACK OUTERTRAN équivaut à 'ROLLBACK log jusqu'au LSN 1'. Vous ne pouvez pas "ignorer" des parties du journal. Vous devez donc annuler chaque opération dans le journal jusqu'à ce que LSN 1 (lorsque le point de sauvegarde OUTERTRAN a été créé) soit atteint.
D’autre part, si vous émettiez ROLLBACK INNERTRAN lors de la dernière opération, le moteur restait en arrière jusqu’au LSN 3 (où le point de sauvegarde "INNERTRAN" était inséré dans le journal), préservant ainsi LSN 1 et LSN 2 (c.-à-d. le premier INSERT).
Pour un exemple pratique de points de sauvegarde, voir Traitement des exceptions et transactions imbriquées .