I have just read about TransactionScope
. It is very good and informative.
First of all, I was wondering if I really need transactions in MVC 4 / EF 6+. The reason for that is we always invoke DbContext.SaveChanges()
to save changes. I'm wondering if SaveChanges()
is something that simulates transaction close meaning if I invoke SaveChanges()
I commit a transactions.
On the other hand, if I need transactions, then how to implement TransactionScope
in MVC / EF applications. My scenario is something similar to the steps below:
I also provided code. As you can see if something goes wrong in the middle I have inconsistent data. I would be grateful for some examples on how to use TransactionScope
. I may also need more to save in other tables. I would like to be certain either I save everything or nothing, such that I save everything if transaction is OK or roll back anything that happened up to the problem.
Thanks.
[HttpPost]
public ActionResult Edit(ApplicationViewModel viewmodel)
{
using(MyDbCOntext dbContext = new MyDbContext())
{
if(!MoselState.IsValid)
return View(application);
// Copy old data from database and assign to an object
ApplicationArchive applicationOld = CopyApplicationFromDB(db, viewmodel.ApplicationID);
// Update model
if (TryUpdateModel(applicationNew), null, null, new string[] { "ApplicationID" })
{
try
{
dbContext.Entry(userToUpdate).State = EntityState.Modified;
dbContext.SaveChanges();
// Archive old application
ApplicationArchive applicationNew = CopyApplicationFromDB(db, viewmodel.ApplicationID);
try
{
dbContext.ApplicationsArchive.Add(applicationOld);
dbCOntext.ApplicationsArchive.Add(applicationNew);
dbContext.SaveChanges();
// Register user activity
string username = GetUserNameFromCookie();
UserActivity useractivity = new UserActivity() { UserName = username, activity = "edit", Table = "application" };
try
{
dbContext.UserActivities.Add(useractivity);
dbContext.SaveChanges();
return RedirectView("Index");
}
}
}
catch
{
ModelState.AddModelError("", "Cannot update this application");
}
}
//
return View(application);
}
}
You need to wrap your database operation within a DbContextTransaction. See this link for Entity Framework transaction examples: https://msdn.microsoft.com/en-us/data/dn456843.aspx