User Not Exist
User Not Exist

Reputation: 109

Does C# TransactionScope rollback if an exception is thrown while committing?

According to Microsoft documentation:

TransactionScope.Complete is merely a way of informing the transaction manager of your status, the actual work of committing the transaction by the transaction manager occurs after the last line of code in the using block. The transaction manager decides to commit or rollback based on whether the TransactionScope.Complete method was called.

So what happens if an exception (such as internet down, database connection closed) occurs in the midst of committing the transactions? Will it rollback or throw a TransactionScope exception?

using (TransactionScope transactionScope = new TransactionScope())
{
    WriteToCloudDatabase(input);
    WriteToCloudDatabase(input);    // I know it will rollback if exception thrown in here.
    transactionScope.Complete();
    // Will it rollback if exception thrown in here? (while committing transactions)
}

Upvotes: 1

Views: 5204

Answers (2)

User Not Exist
User Not Exist

Reputation: 109

Just found the answer: It will rollback and throw a TransactionException.

According to the Microsoft documentation, TransactionScope commits the transactions by calling the CommittableTransaction.Commit method.
https://docs.microsoft.com/en-us/dotnet/framework/data/transactions/implementing-an-implicit-transaction-using-transaction-scope

Let's see what the CommittableTransaction.Commit method do:

When this method is called, all objects that have registered to participate in the transaction are polled and can independently indicate their vote to either commit or roll back the transaction. If any participant votes to roll back the transaction, it is rolled back and this method throws a TransactionException exception. This is a normal occurrence for a transaction and your code should catch and process such exceptions.

Microsoft documentation on CommittableTransaction Class: https://docs.microsoft.com/en-us/dotnet/api/system.transactions.committabletransaction.commit?view=net-5.0#System_Transactions_CommittableTransaction_Commit

try
{
    using (TransactionScope transactionScope = new TransactionScope())
    {
        WriteToCloudDatabase(input);
        transactionScope.Complete();
    }
}
catch (TransactionException)
{
    // If something wrong happens while committing the transaction,
    // it will rollback and throw this exception.
}
catch (Exception)
{
    // If something wrong happens before committing the transaction,
    // it will rollback and that exception will be caught in here.
}

Upvotes: 1

Alexandre Caprais
Alexandre Caprais

Reputation: 46

When disposing the TransactionScope. If the Complete method has been called, the transaction manager will commit the transaction. If an exception is raised by any code after the Complete method call, as the Complete method has already been called, when the transactionScope is disposed, the transaction manager will commit the transaction.

If the transaction manager fail to commit the transaction due to connection loss, all opened transactions are expected to be rollbacked by the database itself.

Upvotes: 1

Related Questions