sql-serversql-server-data-toolsdatabase-projectdacpacsqlpackage

SSDT Project publish transactional deployment


I am using SQLPackage.exe utility together with Database project's publish profiles to run changes to the SQL Server database.

From my understanding, this is the deployment process:

Pre-Deployment Script


Main Deployment


Post-Deployment Script


I have "Include transactional scripts" option checked in the publish profile advanced settings, however, that seems to apply to Main Deployment section only.

My questions is: If Main deployment fails, is Pre-Deployment script committed? As well as, if Post-Deployment script fails, does Pre-Deployment changes and Main Deployment changes are being committed?

Is it possible to make publish script "Atomic" - Everything succeeds or fails as a single unit?

Thank you.


Solution

  • You should simply open the transaction in the pre script and commit it in the post script. It is very similar code like SSDT generates when you set this setting on.

    Pre script:

    IF (SELECT OBJECT_ID('tempdb..#tmpErrors2')) IS NOT NULL DROP TABLE #tmpErrors2
    GO
    CREATE TABLE #tmpErrors2 (Error int)
    GO
    SET XACT_ABORT ON
    GO
    SET TRANSACTION ISOLATION LEVEL READ COMMITTED
    GO
    BEGIN TRANSACTION
    GO
    
    
    
    --Your prescript part goes here
    
    
    
    GO
    IF @@ERROR <> 0
       AND @@TRANCOUNT > 0
        BEGIN
            ROLLBACK;
        END
    
    IF @@TRANCOUNT = 0
        BEGIN
            INSERT  INTO #tmpErrors2 (Error)
            VALUES                 (1);
            BEGIN TRANSACTION;
        END
    

    Post script:

    GO
    IF @@ERROR <> 0
       AND @@TRANCOUNT > 0
        BEGIN
            ROLLBACK;
        END
    
    IF @@TRANCOUNT = 0
        BEGIN
            INSERT  INTO #tmpErrors2 (Error)
            VALUES                 (1);
            BEGIN TRANSACTION;
        END
    
    
    GO
    
    IF EXISTS (SELECT * FROM #tmpErrors2) ROLLBACK TRANSACTION
    GO
    IF @@TRANCOUNT>0 BEGIN
    PRINT N'Post/Pre script finished'
    COMMIT TRANSACTION
    END
    ELSE PRINT N'Pre/Post scripts failed'
    GO
    DROP TABLE #tmpErrors2
    GO