1

There is a project that is developed by asp.net mvc 4 and entity framework 5. Its architecture is three-layer,there are repository ,service and UI.

now there is a problem: where is invoking the save function?

1)put the save in service layer.

if invoke InventoryService.UpdateInventory success,but genericRepository.unitOfWork.SaveChanges[2] failed,there is inconsistency of data.

code:

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
    }
}
//note the _genericRepository is same.

2) add transaction in service if some function invoke OrderService.UpdateOrder and it contains save function also.so we have to add transation in the funciton. there are nested transaction, which generate serious performance problem.

code:

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

3) put the save in Web layer. The way add unnecessary duty to UI and destroy n-layer architecture.

code:

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

so where is the best place for save function?

Gwenc37
  • 2,064
  • 7
  • 18
  • 22
jun_eric
  • 11
  • 1

1 Answers1

1

The top layer/entry point. It's the only place that can know which things should be in the same transaction.

In this case the MVC controller action.

If you are using the Command/Query separation pattern the command would control the transaction since each command then represents a use case.

jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • Thank you,jgauffin.Now i should learn Command/Query separation. because i'm newer ,could not sign your answer useful,vary sorry. – jun_eric Jun 21 '14 at 04:08
  • no. The answer if you are not using CQS was `In this case the MVC controller action` – jgauffin Jun 21 '14 at 06:45