Can LINQ BeginTransaction work with new Context?

My project uses Ninject for development, for example I wrote 2 functions to insert or update into a database

public class PersonRepository : IPersonRepository {

    private readonly DbContext _context;

    public PersonRepository(DbContext context) {
        _context = context;
}

    public void InsertToDB(Person obj) {
        _context.Persons.Add(obj);
        _context.SaveChanges();
}   

    public void UpdateToDB(Person obj) {
        _context.Persons.Attach(obj);
        _context.SaveChanges();
    }   
}

      

And in the controller, I declare the same DbContext and using a transaction:

public class PersonController : Controller {

    private readonly DbContext _context;
    private readonly IPersonRepository _repository;

    public PersonController(DbContext context, IPersonRepository repository) {
        _context = context;
        _repository = repository;
    }

    public ActionResult Index() {
        return View();
    }

    [HttpPost]
    public ActionResult ExecuteToDb(Person person1, Person person2) {
        using (var transaction = _context.Database.BeginTransaction(IsolationLevel.ReadCommitted)) {
            try {
                _repository.InsertToDB(person1);
                _repository.UpdateToDB(person2);

                transaction.Commit();
            } catch (Exception) {
                transaction.RollBack();
            }
        }
    }
}

      

So if InsertToDB()

or UpdateToDB()

throws any exceptions, can the transaction be rolled back?

I am worried about this because I think the _context Controller and the Repository are different, I cannot test it right now, help me, thanks!

+3


source to share


1 answer


You have three options. First, you can configure Ninject to use the same DbContext instance for your PersonController and your PersonRepository. You do this by setting up your binding to use InRequestScope (). Then you can call BeginTransaction on the same context.

Alternatively, you can simply add the BeginTransaction, CommitTransaction and RollBackTrasaction methods to our IRepository class and implement them in your repository.



The third option is to simply create a new TransactionScope () instead of calling BeginTransaction in the context.

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, 
       new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted, 
                                Timeout = TransactionManager.MaximumTimeout }))
{
    _repository.InsertToDB(person1);
    _repository.UpdateToDB(person2);

    // if exception occurs, Complete will not get called, so transaction
    // is automatically rolled back when Dispose is called when using()
    // goes out of scope.  If Complete is called, then Commit is called.
    scope.Complete();
}

      

+2


source







All Articles