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();
}
}