LINQ BeginTransaction可以与新上下文一起工作吗?



我的项目是使用Ninject来开发,例如,我写了2个函数来插入或更新数据库

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

在Controller中,我声明了相同的DbContext并使用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();
            }
        }
    }
}

所以如果InsertToDB()UpdateToDB()抛出任何异常,事务可以回滚吗?

我担心它,因为我认为控制器和存储库的_context是不同的,我现在无法测试它,帮助我,谢谢!

这里有三个选项。首先,你可以配置Ninject为你的PersonController和PersonRepository使用相同的DbContext实例。您可以通过配置绑定来使用InRequestScope()来实现这一点。然后,你可以调用BeginTransaction,它是相同的上下文。

或者,你可以在IRepository类中添加BeginTransaction, CommitTransaction和rollbacktransaction方法,并在你的Repository中实现它们。

第三个选择是只创建一个新的TransactionScope(),而不是在上下文上调用BeginTransaction。

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

相关内容

  • 没有找到相关文章

最新更新