0

I am not sure how to describe the problem, so I will do the best I can and answer any questions.

My project is a Database Project for SQL Server 2008 (client dependent). Within that project I have a series of Seed Scripts that are compiled into a single sql script. The bulk of those seed scripts deal with inserting a large number of VARBINARY records (200MB+ worth of inserts). Since Visual Studio (and most other text editors) have trouble dealing with large files, I have the inserts logically split out into different files. Each file is wrapped in a transaction. The inserts themselves are constructor inserts.

The problem I have is each transaction commits without error. However I am getting the incorrect number of records in the finished database. Or the other effect I am seeing is zero records in the resulting table. While the scripts run, I see records inserted but once the script completes all the records are gone! So ... very confused. Any insight as to why I might be seeing this behavior would be great!

Each is laid out like e.g.

BEGIN TRANSACTION AdBannerBlackEagle
PRINT N'BEGIN TRANSACTION AdBannerBlackEagle'

PRINT N'AdBanner BlackEagle English'

INSERT INTO [dbo].[ContentImageTemplateDetails]
    ([ContentImageTemplateId]
    ,[ContentImageTemplateDetailsCodeKey]
    ,[Data]
    ,[Checksum]
    ,[ContentType]
    ,[RegionID]
    ,[LanguageCode]
    ,[DisplayOrder]
    ,[CreatedDate]
    ,[ModifiedDate]
    )
VALUES
    (
        1,
        'AdBanner'
        ,0xFFD8FFE10018457869660000<reduced for brevity>
        ,'5F44C068DEE6507FDB01F52C9D66C291E06896DAACB2A6D687BDCE0EE3A5CE47'
        ,'jpg'
        ,5
        ,'en-DE'
        ,1
        ,SYSDATETIMEOFFSET()
        ,SYSDATETIMEOFFSET()
    ),
    (
        1,
        'AdBanner'
        ,0xFFD8FFE10018457869660000<reduced for brevity>
        ,'059FF9C3FCAF65EEDC01719D791AE88791C5C1A647BBC7F229A5F3FB0862D54D'
        ,'jpg'
        ,5
        ,'de-DE'
        ,2
        ,SYSDATETIMEOFFSET()
        ,SYSDATETIMEOFFSET()
    )
GO

COMMIT TRANSACTION AdBannerBlackEagle
PRINT N'COMMIT TRANSACTION AdBannerBlackEagle'
5
  • 1
    Check the value of @@TRANCOUNT after the commit in your example. Committing nested transaction only decrement this count. When a commit occurs and the count finally reached 0 - THEN the transaction is committed Commented Sep 6, 2016 at 17:44
  • Ok, cool I will take a look at that too. Might take me a minute to respond. I realized I should add more messaging around transactions that could become rolled back.
    – Mr. Young
    Commented Sep 6, 2016 at 17:48
  • 1
    Nested transaction can be 'difficult' to debug. I noticed you are naming your transactions. Remember, you can SAVE a transaction with a name and rollback a 'named' transaction. A rollback without a 'name' will roll EVERYTHING back to the outermost begin. COMMITS decrement the @@TRANCOUNT. When it reaches zero, the the ENTIRE transaction is committed - see this link for more information - technet.microsoft.com/en-us/library/ms189336(v=sql.105).aspx Commented Sep 6, 2016 at 17:54
  • I am restructuring my transaction blocks to read something very similar to the below comment
    – Mr. Young
    Commented Sep 6, 2016 at 17:58
  • Declare @TransactionName varchar(255) SET @TransactionName = 'Name' Begin Begin Try BEGIN TRANSACTION @TransactionName -- code COMMIT TRANSACTION @TransactionName End Try Begin Catch DECLARE @ErrorMessage NVARCHAR(4000), @ErrorSeverity INT, @ErrorState INT; SELECT @ErrorMessage = ERROR_MESSAGE(), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE(); RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState); Rollback transaction @TransactionName; Print @TransactionName + N' Rolled Back' End Catch End GO
    – Mr. Young
    Commented Sep 6, 2016 at 17:59

1 Answer 1

1

You state that:

each transaction commits without error

I believe there is a nuance here that is being overlooked. The DML statement can cause an error and the COMMIT still happens (hence "nothing" is Committed) because this is not being done in a TRY...CATCH construct (and I assume that you are not setting XACT_ABORT ON at the beginning of the scripts). I believe that the DML statements are getting an error (possibly a truncation one?) but the Commit then runs and succeeds.

AND / OR:

Another possibility is that you have an unmatched BEGIN TRAN in one of the scripts (meaning, no matching COMMIT). Or how exactly are you running these scripts? If there is an open Transaction that is not committed by the time the scripts end, then the Transaction will be automatically rolled-back.

Individual DML / DLL statements, when executed outside of an explicit BEGIN TRAN...COMMIT/ROLLBACK are already their own Transaction and are automatically committed. Hence, you do not need BEGIN TRAN...COMMIT for single statements, unless you have some additional logic after the DML / DDL statement that conditionally decides on COMMIT or ROLLBACK. Also, unless you need the ability to discard portions of work that covers many statements within a single Transaction without rolling back the ALL statements, then you don't need to name them. It looks like you should start by removing the BEGIN TRAN / COMMIT / ROLLBACK statements, but still keep the TRY...CATCH statements that you are adding.

6
  • Finally was able to get through it. I added Try Catch blocks and added logic to rollback named transactions. This helped a lot with performance too!
    – Mr. Young
    Commented Sep 8, 2016 at 18:01
  • So what was the actual problem causing the "missing" values? A mismatched BEGIN TRAN, truncation errors, or something else? Commented Sep 8, 2016 at 18:02
  • 1
    Silent rollback was unwinding the whole nested transaction.
    – Mr. Young
    Commented Sep 8, 2016 at 18:03
  • Ah, ok. so that means "unmatched" BEGIN TRAN. Again, if you are only doing a single statement each time, I would rip the BEGIN TRAN / COMMIT / ROLLBACK out of it. Commented Sep 8, 2016 at 18:04
  • I wish I was! But the nature of the inserts were very large and for a long time I was running into memory issues during the insert.
    – Mr. Young
    Commented Sep 8, 2016 at 18:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.