sqlschool.gr logo

articles

Articles of SQLschool.gr Team

How do nested transactions actually behave in SQL Server?

Fivi Panopoulou - Sotiris Karras
Monday 10 October 2016

Στον SQL Server μας δίνεται η δυνατότητα να ορίσουμε ένα ή περισσότερα transactions μέσα σε ένα ήδη ανοιχτό transaction. Ποια είναι όμως η συμπεριφορά των transactions όταν κάνουμε rollback ή commit ένα εσωτερικό transaction;

Αρχικά, θα δημιουργήσουμε ένα πίνακα με δύο πεδία με τον οποίο θα δοκιμάσουμε τα δύο σενάρια.

--Table to test nesting 
CREATE TABLE NestingTransactions (Id INT IDENTITY(1,1), Description NVARCHAR(20));
GO

Στο πρώτο σενάριο θα δοκιμάσουμε να κάνουμε rollback το εσωτερικό transaction:


BEGIN TRANSACTION OuterTransaction;
    --The outer transaction executes an insert
    SELECT @@TRANCOUNT AS FirstTran;
    INSERT INTO NestingTransactions (Description) VALUES ('Description1'),('Description2'),('Description3');
    
    SELECT COUNT(*) AS InsertedRows
    FROM NestingTransactions;

    BEGIN TRANSACTION;
        --The inner transaction adds one more rows, then it rollbacks
        SELECT @@TRANCOUNT AS SecondTran;
        INSERT INTO NestingTransactions (Description) VALUES ('Description4');
        
        SELECT COUNT(*) AS InsertedRows
        FROM NestingTransactions;

    ROLLBACK TRANSACTION;

    SELECT @@TRANCOUNT AS FinalTranCount;
    SELECT COUNT(*) AS FinalRows
    FROM NestingTransactions;

-- FirstTran: 1
-- InsertedRows: 3
-- SecondTran: 2
-- InsertedRows: 4
-- FinalTranCount: 0
-- FinalRows: 0

Το πρώτο πράγμα το οποίο παρατηρούμε είναι ότι το rollback το οποίο καλούμε αφού έχουμε κάνει begin το εσωτερικό transaction, στην πραγματικότητα κάνει rollback το εξωτερικό και κατά συνέπεια μετά την εκτέλεσή του ο πίνακας θα είναι άδειος. Τελικά, και ενώ μετά από δύο συνεχόμενα BEGIN TRANSACTION η τιμή του @@TRANCOUNT είναι όπως θα περιμέναμε 2, μετά το ROLLBACK TRANSACTION η τιμή του επιστρέφει σε μηδέν καθώς δεν έχουμε πλέον κανένα transaction ανοιχτό.

Στο επόμενο σενάριο, θα προσπαθήσουμε να κάνουμε commit το εσωτερικό transaction και στην συνέχεια rollback το εξωτερικό:

BEGIN TRANSACTION;
    SELECT @@TRANCOUNT AS FirstTran;
    INSERT INTO NestingTransactions (Description) VALUES ('Description1'),('Description2'),('Description3');

    BEGIN TRANSACTION;
        SELECT @@TRANCOUNT AS SecondTran;
        INSERT INTO NestingTransactions (Description) VALUES ('Description4');
    COMMIT;
    SELECT @@TRANCOUNT AS TranCountAfterInnerCommit;
ROLLBACK;
GO

SELECT COUNT(*) AS FinalRows
FROM NestingTransactions;
-- FirstTran: 1
-- SecondTran: 2
-- TranCountAfterInnerCommit: 1
-- FinalRows: 0

Και σε αυτό το σενάριο, στο τέλος ο πίνακας δεν θα περιέχει καμία γραμμή. Το @@TRANCOUNT μετά το commit του εσωτερικού transaction, θα μειωθεί κατά 1 αλλά μετά το ROLLBACK το INSERT που έγινε στο nested transaction θα "χαθεί".

Στον SQL Server λοιπόν, αν και έχουμε την δυνατότητα να δηλώσουμε nested transactions, στην πραγματικότητα δεν έχουμε την συμπεριφορά που θα περίμενε κανείς από αυτά. Αυτό που γίνεται τελικά, είναι ότι ορίζει το εξωτερικό transaction, αρκεί να υπάρχει η σύμφωνη γνώμη των εσωτερικών.

Leave your comment

 


 


   




   
captcha

 

Fivi Panopoulou

Fivi Panopoulou

Το 2007 ξεκίνησα τις σπουδές μου στη σχολή Ηλεκτρολόγων Μηχανικών και Μηχανικών Υπολογιστών στο Εθνικό Μετσόβιο Πολυτεχνείο.Κατά την διάρκεια των σπουδών μου εκεί αγάπησα τον προγραμματισμό και τα συστήματα πληροφορικής, καθώς επίσης απέκτησα το ιδιαίτερο ενδιαφέρον μου για τις βάσεις δεδομένων. Κατά την διάρκεια της διπλωματικής μου ασχολήθηκα με ζητήματα ανωνυμοποίησης δεδομένων και την ανάπτυξη σχετικού εργαλείου. Τα τελευταία χρόνια των σπουδών μου, μου δόθηκε η ευκαιρία να ασχοληθώ περισσότερο και να διευρύνω τους ορίζοντές μου ως Microsoft Student Partner και μέσω της κοινότητας Student Guru. Στα πλαίσια των κοινοτήτων αυτών, ξεκίνησα να ασχολούμαι με παρουσιάσεις αλλά και να γνωρίζω τον SQL Server. Από την πρώτη στιγμή που ασχολήθηκα μαζί του, συνειδητοποίησα πόσο ήθελα να εμβαθύνω τις γνώσεις μου σχετικά με αυτόν και τα συστήματα διαχείρισης βάσεων δεδομένων γενικότερα, πράγμα που προσπαθώ να κάνω έκτοτε. Πριν χρόνια είχα την τύχη να συμμετέχω στο πρόγραμμα mentoring, μέσω του οποίου γνώρισα τον κ. Χατζηπαυλή. Από τότε συμμετέχω στην ομάδα του SQLschool.gr.


Sotiris Karras

Sotiris Karras

Είμαι απόφοιτος της σχολής Ηλεκτρολόγων Μηχανικών και Μηχανικών Υπολογιστών του Εθνικού Μετσόβιου Πολυτεχνείου και στα ενδιαφέροντά μου συμπεριλαμβάνεται o τομέας του Knowledge and Data Engineering. Πιο συγκεκριμένα, έχω ασχοληθεί ακαδημαϊκά και ερευνητικά με τον τομέα του data privacy και data anonymity, ενώ πάθος μου είναι ό,τι έχει να κάνει με relational databases και data management. Στο παρελθόν, έχω συνεργαστεί με την Microsoft Hellas ως Microsoft Student Partner για ακαδημαϊκές δραστηριότητες και ήμουν μέρος του MVP mentoring προγράμματός της, στο οποίο είχα την τύχη να γνωρίσω τον κ. Χατζηπαυλή.

Episode

Row-level Security in SQL Server

More Episodes...

Tip

Refresh Intellisence in SSMS

Για να κάνουμε refresh το intellisence μέσα στο SSMS αρκεί να πατήσουμε Ctrl+Shift+R

More Tips...

Info graph

a day in data

Become a member

If you want to receive updates from us become a member to our community.

Connect

Explore

Learn


sqlschool.gr © 2010-2023 All rights reserved

This site uses cookies for operational and analytics purposes only. By continuing to browse this site, you agree to their use.