A Transaction Scope Or Nested Transaction

A transaction scope can select and manage the ambient transaction automatically. Due to its ease of use and efficiency, it is recommended that you use the Transaction Scope class when developing a transaction application.

Completing a transaction scope

When your application completes all the work it wants to perform in a transaction, you should call the Complete method only once to inform the transaction manager that it is acceptable to commit the transaction.

TransactionAbortedException

A TransactionAbortedException is thrown if the scope creates the transaction, and the transaction is aborted. A TransactionIndoubtException is thrown if the transaction manager cannot reach a Commit decision. No exception is thrown if the transaction is committed.

Rolling back a transaction

If you want to rollback a transaction, you should not call the Complete method within the transaction scope. For example, you can throw an exception within the scope. The transaction in which it participates will be rolled back.

Example

As a system admin if you want to update product and category details as a single unit, use the Transaction Scope class to complete this task.

With the below example, you can compare source database products and categories, compare all data, and update all data to destination data. If insert, update, or delete fails for any single process transaction scope aborts all data, if the transaction is successful for both processes then only it proceeds for commit.

public void UpdateProductsAndCategories(List<Categories> ProductCategories, List<Products> LanguageSpecificXmlDocuments)
{
    var isupdatedProducts = false;
    var isUpdatedCategories = false;
    var updateProductWatch = new Stopwatch();
    updateProductWatch.Start();
    try
    {
        // Retrieve All categories from source Database   
        var ProductCategoriesFromSource = GetProductCategoriesfromSourceDB();
        // Get all products from source database  
        var SourceProducts = GetProductsfromSourceDB();
        // Retrieve All categories from destination Database   
        var ProductCategoriesFromDest = GetProductCategoriesfromDestDB();
        // Get all products from destination database  
        var DestinationProducts = GetProductsfromDestDB();
        var option = new TransactionOptions
        {
            IsolationLevel = IsolationLevel.ReadCommitted,
            Timeout = TimeSpan.FromSeconds(Convert.ToInt32(5000))
        };
        // here we handle nested transaction with TransactionScope logic   
        using (var scopeOuter = new TransactionScope(TransactionScopeOption.Required, option))
        {
            // 1. Insert,update,Delete products logic   
            // first compare data from source to destination and then apply updation logic.   
            // perform insert,update,delete using sql stored procedure or sql statemen 
            // isupdatedProducts = UpdateProducts(SourceProducts, DestinationProducts);   
            
            // 2. Insert,update,Delete product categories logic   
            // first compare data from source to destination and then apply updation logic.   
            // perform insert,update,delete using sql stored procedure or sql statement   
            isUpdatedCategories = UpdateBasicProductCategories(ProductCategoriesFromSource, ProductCategoriesFromDest);
            
            // The Complete method commits the transaction. If an exception has been thrown,   
            // Complete is not called and the transaction is rolled back.   
            // if all 2 updater process successful then go for commit else rollback all transactions.   
            if (isUpdatedCategories && isupdatedProducts)
            {
                // commit transaction   
                scopeOuter.Complete();
                var SucessMsg = string.Format("Successfully Updated products and categories.");
                Console.WriteLine(SucessMsg);
                updateProductWatch.Stop();
            }
            // transaction is rolled back.   
            else
            {
                // if failed updating product data   
                if (!isupdatedProducts)
                {
                    // rollback transaction   
                    scopeOuter.Dispose();
                    var errormsg = string.Format("Failed updating products, rolls back the all current transaction's for products.");
                    Console.WriteLine(errormsg);
                    updateProductWatch.Stop();
                }
                // if failed updating product Categories stop proceeding and rollback all current transaction   
                if (!isUpdatedCategories)
                {
                    // rollback transaction   
                    scopeOuter.Dispose();
                    var errormsg = string.Format("Failed updating product categories, rolls back the all current transaction's for product categories.");
                    updateProductWatch.Stop();
                }
            }
        }
    }
    catch (SqlException ex)
    {
        var errormsg = string.Format("Failed updating, issue is : " + ex.Message);
        updateProductWatch.Stop();
    }
    // General exception handling   
    catch (Exception ex)
    {
        var errormsg = string.Format("Failed updating, issue is : " + ex.Message);
        updateProductWatch.Stop();
    }
}


Similar Articles