最近在做一个小项目,用的ASP.NET MVC 4和EF 5。采用的架构设计是普通的三层式,即Repository,Service和Web层。
在开发过程中发现了一个问题——在哪一层调用EF的save方法。
如果放在Service的某个方法中,就出现了这样一个问题:
例:
InventoryService有一个方法是UpdateInventory,方法中调用了unitOfWork.SaveChanges()方法
OrderService中有一个方法是UpdateOrder,在其中先调用了InventoryService.UpdateInventory方法,然后调用了unitOfWork.SaveChanges方法
代码如下:
public class InventoryService
{
private GenericRepository _genericRepository;
public InventoryService(GenericRepository genericRepository){
_genericRepository = genericRepository;
}
public int UpdateInventory()
{
...
_genericRepository.unitOfWork.SaveChanges(); //1
}
}
public class OrderService
{
private GenericRepository _genericRepository;
public OrderService(GenericRepository genericRepository){
_genericRepository = genericRepository;
}
public int UpdateOrder()
{
InventoryService.UpdateInventory();
...
_genericRepository.unitOfWork.SaveChanges();//2
}
}
//注:这两个函数的_genericRepository;是同一个。
现执行OrderService.UpdateOrder,调用InventoryService.UpdateInventory成功,但调用DgenericRepository.unitOfWork.SaveChanges()方法(2)
失败,导致了数据不一致。
解决方案1:
在UpdateOrder中加事务:
public class OrderService
{
private GenericRepository _genericRepository;
public OrderService(GenericRepository genericRepository){
_genericRepository = genericRepository;
}
public int UpdateOrder()
{
_genericRepository.unitOfWork.BeginTransaction();
try
{
InventoryService.UpdateInventory();
...
_genericRepository.unitOfWork.SaveChanges();//2
_genericRepository.unitOfWork.CommitTransaction();
}
catch()
{
_genericRepository.unitOfWork..RollBackTransaction();
}
}
}
如果此时有另外一个方法调用OrderService.UpdateOrder(),那个方法中也有SaveChanges(),因此也要加事务,这样一来导致事务嵌套事务,效率一定非常低。
解决方案2:
把所有的SaveChanges()方法都放在controller中,这样service中的那些方法随便怎么互相调用都可以,但是又产生了一个问题:
1、如果controller调用是addobject方法,需要返回的object id,那么就无法获取,因为object id在SaveChanges()才会生成。
2、把SaveChanges()放在controller中,好像又违法了分层的意义,controller并不负责这方面的工作。
public class InventoryService
{
private GenericRepository _genericRepository;
public InventoryService(GenericRepository genericRepository){
_genericRepository = genericRepository;
}
public int UpdateInventory()
{
...
}
}
public class OrderService
{
private GenericRepository _genericRepository;
public OrderService(GenericRepository genericRepository){
_genericRepository = genericRepository;
}
public int UpdateOrder()
{
InventoryService.UpdateInventory();
...
}
public void Save()
{
_genericRepository.unitOfWork.SaveChanges();
}
}
public class OrderController : Controller
{
public ActionResult update()
{
OrderService.UpdateOrder();
OrderService.Save();
}
}
在此请问各位牛人,你们是如何处理这个问题的呢?先谢谢了。
可以看看 单元工作模式
一个工作单元savechange一次