Search code examples
transactionsssismsdtc

Can a SSIS package enlist in an existing external transaction?


I've asked a vaguely similar question before (although specific to running the package from xp_cmdshell). My final comment on the matter was to ask what my options were if I want to ensure that the SSIS package enlists in a transaction.

So, is there any way that I can execute a SSIS package and have it participate in an already existing transaction?

The reason for this if for testing purposes we want to:

  • Run the package to load data.
  • Run test(s) against the loaded data.
  • Roll all the loaded data back out.

Thanks, Stuart.


Solution

  • The internet is very quiet on solutions to this issue. I had the same problem and searched everywhere for a solution. SSIS is also unhelpful with the error messages generated when doing it wrong (undocumented error codes). The answer might be a little late but hopefully it'll help someone avoid the wasted time. This is what ended up working for me.

    In a unit test for example wrap the whole process in a TransactionScope:

    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew,new TransactionOptions(){IsolationLevel =IsolationLevel.ReadCommitted}))
            { 
              Application app = new Application();
              Package package = app.LoadPackage(packageFileName, null);
    
              // Can set package settings for test
              package.TransactionOption = DTSTransactionOption.Required;
              package.IsolationLevel = IsolationLevel.ReadCommitted;
    
              // Use this overload for execute
              DTSExecResult result = package.Execute(null, null, null, null, TransactionInterop.GetDtcTransaction(Transaction.Current));
    
              // Test results here inside the scope
    }
    

    Of course you can rearrange this if you want to add data to the database, then extract it via SSIS and then rollback after testing the data.