How to manage transactions in the service layer? - asp.net-mvc

We’re developing a .Net application with the following architecture: presentation layer (using MVC pattern with ASP.Net MVC 2), service layer, data access layer (using repository pattern over Entity Framework).
We’ve decided to put the transaction management in the service layer but we’re not sure about how to implement it. We want to control the transaction entirely at the service layer level. That is, every time a controller calls a method in the service layer, it has to be an atomic operation regarding database updates.
If there were no relation between different services provided in the service layer, then it would be simple: each method should commit the changes at the end of its execution (that is, call the save method on the context it uses). But sometimes services at the service layer work together.
e.g.: we provide a shipment service that has a confirm method which receives the following parameters: the shipment id, a flag indicating if it corresponds to a new customer or an existing one, the customer id (in case the shipment confirmation is for an existing customer) and a customer name (in case it is for a new customer). If the flag is set to "new customer", then the service layer has to (a) create the customer and (b) confirm the shipment. For (a) the shipment service calls the customer service (which already implements the validations and logic needed to create a new customer and store it in the database).
Who should commit the changes in this scenario?
Should the customer service do it? it cannot commit the changes after creating the new customer, because something can go wrong later in the shipment confirmation method, but it has to commit its changes in the case it is call directly (in other use case, provided to create a client).
Should the controller calling the service method do it? but the controller shouldn’t know anything about transactions, we've decided to put all transaction knowladge in the service layer.
A Transaction Manager in the services layer? How to design it?, who calls it and when?
Is there a design pattern for this that we should follow?

I have a Commit() on my service, this only commits if the UnitOfWork is created by the service, if it is passed in the constructor the commit does nothing.
I used a second (internal) constructor for the service:
public class MyService
{
private IUnitOfWork _uow;
private bool _uowInternal;
public MyService()
{
_uow = new UnitOfWork();
_uowInternal = false;
}
internal MyService(IUnitOfWork uow)
{
_uow = uow;
_uowInternal = true;
}
public MyServiceCall()
{
// Create second service, passing in my UnitOfWork:
var svc2 = new MySecondService(_uow);
// Do your stuff with both services.
....
// Commit my UnitOfWork, which will include all changes from svc2:
Commit();
}
public void Commit()
{
if(!_uowInternal)
_uow.Commit();
}
}

In a similar architecture with WCF and L2S instead of EF, we chose to use transactions in the main service interface implementation class. We used TransactionScope to achieve this:
public void AServiceMethod() {
using(TransactionScope ts = new TransactionScope()) {
service1.DoSomething();
service2.DoSomething();
ts.Complete();
}
}
The main disadvantage is that the transaction may get big. In that case, if for example one of the service calls in the transaction block requires only readonly access, we wrap it in a nested TransactionScope(TransactionScopeOption.Suppress) block to prevent locking rows/tables further in the transaction lifetime.

Related

DDD inject repository on domain service VS orchestrate flow on application service

I am currently working with DDD and I have a question about application services VS domain services VS repositories interfaces
As I know:
Application services are used for handle the flow of use cases, including any additional concerns needed on top of the domain's.
Domain services are used for encapsulate such behaviors that do not fit in a single domain object.
So, taking account into, for example, this use case:
"when you create a new Car entity(uuid,name) in the system, the car name must be unique (no more cars exist with this name) or the car name can't contains another car name from database as substring",for example, just an example of use case that forces me to take a look into other entities in the repository when I am creating an object
So the question is: Where should I do the checks and/or inject the repository Interface?
- Opt 1) In the application service, injecting the RepositoryCarInterface, do the checks and save the Car:
class CreateCarApplicationService
{
private carRepositoryInterface $carRepository;
public function __construct(CarRepositoryInterface $carRepository)
{
$this->carRepository = $carRepository;
}
public function __invoke(string $carUuid, string $carName): void
{
$this->ensureCarNameIsUnique($CarName);
$car = new Car($carUuid,$carName);
$this->carRepository->save($car);
}
private function ensureCarNameIsUnique(string $carName): void
{
$CarSameName = $this->carRepository->findOneByCriteria(['name' => $carName]);
if ($carSameName) {
throw ExceptionCarExists();
}
}
}
- Opt 2) Create this logic into a domain service (with the purpose of keep the domain logic near to the domain objects) and invoke it from a more simple application service which has the final responsibility of saving the model interacting with database:
class CreateCarDomainService
{
private carRepositoryInterface $carRepository;
public function __construct(carRepositoryInterface $carRepository)
{
$this->carRepository = $carRepository;
}
public function __invoke(string $carUuid, string $carName): Car
{
$this->ensureCarNameIsUnique($CarName);
return new Car($carUuid,$carName);
}
private function ensureCarNameIsUnique(string $carName): void
{
$CarSameName = $this->carRepository->findOneByCriteria(['name' => $carName]);
if ($carSameName) {
throw ExceptionCarExists();
}
}
}
class CreateCarApplicationService
{
private carRepositoryInterface $carRepository;
private CreateCarDomainService $createCarDomainService;
public function __construct(CarRepositoryInterface $carRepository)
{
$this->carRepository = $carRepository;
$this->createCarDomainService = new CreateCarDomainService($carRepository)
}
public function __invoke(string $carUuid, string $carName): void
{
$car = $this->createCarDomainService($carUuid,$carName);
$this->carRepository->save($car);
}
}
I am not very sure about the fact of injecting repository interfaces into domain services, because of as Evans said:
A good SERVICE has three characteristics:
-The operation relates to a domain concept that is not a natural part of an entity or value object
-The interface is defined in terms of other elements of the domain model
-The operation is stateless
But I want to push my domain logic as deep as I cant
And, as I read in other StackOverflow posts, inject repository in domain object is not allowed/recommended:
Do you inject a Repository into Domain Objects?
Should domain objects have dependencies injected into them?
Option 1
The ideal case is that repositories are only used by your orchestration (application) layer and have absolutely nothing to do with your domain model (domain layer). Thus, your repo would be injected into your orchestrator, not into your domain model (option 1).
In your case, you have an orchestration layer that
has a cars repository injected into it
loads names of cars from the repository
uses DDD to validate the name of the new car is not in the names of existing cars, etc.
if yes: create the car in the domain; if no: fail domain validation
uses the repo to persist the change in state on the domain (in this case, saving the new car using the repo)
returns results (if a request/reply scenario)
There's a small problem with this though. You could argue that it would be more efficient to take the name of the car and pass it to a query against the repo to see if the name is unique. That's true, but the trade off is that some of your domain logic (checking for uniqueness) has been moved out of the domain to the repo and orchestration layers.
So, consider carefully which you'd prefer.
Option 1, Scenario 1: DDD as much as possible
// inefficient, but we're done with the repo immediately
var carNames = repo.GetCarNames();
// all the following calls are on our domain, easily testable
var carCreator = new CarCreator(names);
var carCreationResult = carCreator.TryCreateCar(carNames, newCar);
if (carCreationResult.Failed) return carCreationResult.Errors;
// finally save and return
repo.Save(carCreationResult.Car);
return carCreationResult.Car;
In the above, TryCreateCar could be implemented as a simple check against a dictionary inside carCreator -- totally within the domain, testable, and not relying on the repo.
Option 1, Scenario 2: Be efficient
// uniqueness check requires repo; mixes in domain concept of uniqueness with a repo query
var canCreateCar = repo.IsCarUnique(newCar.Name)
if (!canCreateCar) return error;
// creation separated from uniqueness check; wouldn't have to check uniqueness in TryCreateCar (it was checked above)
var carCreator = new CarCreator(newCar);
var carCreationResult = carCreator.TryCreateCar(carNames, newCar);
if (carCreationResult.Failed) return carCreationResult.Error;
// finally save and return
repo.Save(carCreationResult.Car);
return carCreationResult.Car;
That IsCarUnique method on the repo is hiding some domain logic though!
Option 2
We'll dismiss this option because we simply don't want a non-domain concern to be a dependency of our domain model. That's the sum-total of the reason to avoid this. When you take a non-domain concern and make it a dependency, your domain model becomes harder to test.
Worse, I've seen code that interleave concerns. Imagine the case of an orchestration layer that gets some entities via a repo, makes some changes to the domain, saves some entities, loads some more, injects the repo into the domain so it can use the repo to load some more, and then finally save. That's an untestable and hard to read/maintain mess!
In Summary
Option 1 Scenario 1 allows us to keep all of our domain concerns together and encapsulated. This is well worth it. If the rules change, we only have to modify our domain model's data and behavior, leaving the orchestration intact.

Handling transaction with UnitOfWork and EF

I'm using Entity Framework 5.0 and MVC4. I have couple of domains. Each of them has its own DbContext (which uses appropriate tables), repository and service. I also implemented UnitOfWork.
Handling specific flow in transaction inside one service for specific domain is simple. I'm doing some operations on tables and at the end I'm invoking UnitOfWork.Save, which behaves as Transaction.Commit.
But lets assume I have a case in which I have to invoke operations for two different domains and this two operations must be put inside one transaction. I have access to services for domains from controller so this actions are invoked from there. At the moment I can see three solutions:
I must have UnitOfWork in controller and call Save method at the end (I don't like this idea).
Create some service in which I will have UnitOfWork and access to both services (actually it is the same solution as above, but I'm moving logic to separate class)
I have to create additional TransactionScope inside controller and commit it at the end
Please let me know what option you think is the best. If you have any other than the three above, let me know. Or maybe something is wrong with my concept? I mean domains and their db contexts?
Assuming your UnitOfWork implementation supports normal Transactions in .NET, you can do the following and they should enroll in the currently running transaction.
protected TransactionScope CreateTransactionScope()
{
var options = new TransactionOptions();
options.IsolationLevel = IsolationLevel.ReadCommitted;
options.Timeout = TransactionManager.MaximumTimeout;
return new TransactionScope(TransactionScopeOption.Required, options);
}
using (var scope = this.CreateTransactionScope())
{
// do operations with context 1
// do operations with context 2
scope.Complete();
}

persisting MVC data to ORM

Java or dotNet world is rich of open source frameworks and libraries. We all like to use Spring and Hibernate almost everywhere.
Everyone agrees that hibernate is a very handy tool.
What Hibernate can do ? well, Basically - Hibernate can track our domain objects changes and persist only modified data to database, that is it.
Basically, That is everything we want. I want to load some records from database, do some modifications to them, and call transaction.commit(), and all modifications get persisted, instantaneously.
That is excelent, right !
But how about web world ? In web applications database session must be closed.
I cannot load some domain objects and wait for user to do modifications through HTTP, and persist those objects after modifications.
We have to use detached objects or DTO. How it works ?
User makes modifications in HTML browser, spring Mvc automatically thransfers those HTML modifiactions to our customized DTO objects using MVC model binding,
then we do some programming effort to transfer modifications from DTO objects to hibernate domain objects and only then we persist them.
For example - we have a web form that updates Customer address, and another form which updates customer details.
We must have two different business layer methods - UpdateAddress() and UpdateDetails(), both methods must accept some kind of DTO,
one represents address information, the other represents details infprmation.
We also have custom logic that transfers data from those 2 DTO to the domain class 'Customer'.
Yes, of course, instead of DTO objects we could reuse our domain classes. But it does not make it simpler.
In both cases we will still have to implement custom logic that transfer modifications to persistent objects,
I cannot persist detached object rightaway, because usually domain classes have lots and lots of properties representing numerous relations, for ex. Customer has - Orders property. When I update customer address I don't want to update its orders.
Is there a beautifull universal way to mapping modifications from mvc model to domain objects without writing a lot of custom code and without risk of overwriting too many fields ?
It's good practice to have a data access layer, which translates into having a repository for each domain object / entity. Furthermore, all repositories share common code so you you naturally have an abstract repository:
public abstract class AbstractRepository<E extends BaseModel> implements Repository<E> {
#PersistenceContext
private EntityManager entityManager;
private Class<E> entityClass;
public AbstractRepository(Class<E> entityClass) {
this.entityClass = entityClass;
}
protected EntityManager getEM() {
return entityManager;
}
protected TypedQuery<E> createQuery(String jpql) {
return createQuery(jpql, entityClass);
}
protected <T> TypedQuery<T> createQuery(String jpql, Class<T> typeClass) {
return getEM().createQuery(jpql, typeClass);
}
#Override
public E merge(E entity) {
return getEM().merge(entity);
}
#Override
public void remove(E entity) {
getEM().remove(entity);
}
#Override
public E findById(long id) {
return getEM().find(entityClass, id);
}
}
It's also good practice to have a service layer where you are to create, update and delete instances of an entity (where you could pass through a DTO to the create and update methods if you so desire).
...
#Inject
private CustomerRepository customerRepository;
public Customer createCustomer(CustomerDto customerDto) {
Customer customer = new Customer();
customer.setEmail(customerDto.getEmail());
...
return customerRepository.merge(customer);
}
public Customer updateCustomerAddress(Customer customer, String address) {
customer.setAddress(address);
return customerRepository.merge(customer);
}
...
So it's up to you how many update methods you want. I would typically group them into common operations such as updating the customer's address, where you would pass the customer Id and the updated address from the front end (probably via ajax) to your controller listening on a specific endpoint. This endpoint is where you would use the repository to find the entity first by Id and then pass it to your service to do the address update for example.
Lastly you need to ensure that the data actually gets persisted, so in Spring you can add the #Transactional annotation either to you Spring MVC controller or to your service that does the persisting. I'm not aware of any best practices around this but I prefer adding it to my controllers so that you're always guaranteed to have a transaction no matter what service you are in.

Difference between Repository and Service Layer?

In OOP Design Patterns, what is the difference between the Repository Pattern and a Service Layer?
I am working on an ASP.NET MVC 3 app, and am trying to understand these design patterns, but my brain is just not getting it...yet!!
Repository Layer gives you additional level of abstraction over data access. Instead of writing
var context = new DatabaseContext();
return CreateObjectQuery<Type>().Where(t => t.ID == param).First();
to get a single item from database, you use repository interface
public interface IRepository<T>
{
IQueryable<T> List();
bool Create(T item);
bool Delete(int id);
T Get(int id);
bool SaveChanges();
}
and call Get(id). Repository layer exposes basic CRUD operations.
Service layer exposes business logic, which uses repository. Example service could look like:
public interface IUserService
{
User GetByUserName(string userName);
string GetUserNameByEmail(string email);
bool EditBasicUserData(User user);
User GetUserByID(int id);
bool DeleteUser(int id);
IQueryable<User> ListUsers();
bool ChangePassword(string userName, string newPassword);
bool SendPasswordReminder(string userName);
bool RegisterNewUser(RegisterNewUserModel model);
}
While List() method of repository returns all users, ListUsers() of IUserService could return only ones, user has access to.
In ASP.NET MVC + EF + SQL SERVER, I have this flow of communication:
Views <- Controllers -> Service layer -> Repository layer -> EF -> SQL Server
Service layer -> Repository layer -> EF This part operates on models.
Views <- Controllers -> Service layer This part operates on view models.
EDIT:
Example of flow for /Orders/ByClient/5 (we want to see order for specific client):
public class OrderController
{
private IOrderService _orderService;
public OrderController(IOrderService orderService)
{
_orderService = orderService; // injected by IOC container
}
public ActionResult ByClient(int id)
{
var model = _orderService.GetByClient(id);
return View(model);
}
}
This is interface for order service:
public interface IOrderService
{
OrdersByClientViewModel GetByClient(int id);
}
This interface returns view model:
public class OrdersByClientViewModel
{
CientViewModel Client { get; set; } //instead of ClientView, in simple project EF Client class could be used
IEnumerable<OrderViewModel> Orders { get; set; }
}
This is interface implementation. It uses model classes and repository to create view model:
public class OrderService : IOrderService
{
IRepository<Client> _clientRepository;
public OrderService(IRepository<Client> clientRepository)
{
_clientRepository = clientRepository; //injected
}
public OrdersByClientViewModel GetByClient(int id)
{
return _clientRepository.Get(id).Select(c =>
new OrdersByClientViewModel
{
Cient = new ClientViewModel { ...init with values from c...}
Orders = c.Orders.Select(o => new OrderViewModel { ...init with values from o...}
}
);
}
}
As Carnotaurus said the repository is responsible for mapping your data from the storage format to you business objects. It should handle both how to read and write data(delete, update too) from and to the storage.
The purpose of service layer on the other hand is to encapsulate business logic into a single place to promote code reuse and separations of concerns. What this typically means for me in practice when building Asp.net MVC sites is that I have this structure
[Controller] calls [Service(s)] who calls [repository(ies)]
One principle I have found useful is to keep logic to a minimum in controllers and repositories.
In controllers it is because it helps keeping me DRY. It's very common that I need to use the same filtering or logic somewhere else and if I placed it in the controller I can't reuse it.
In repositories it is because I want to be able to replace my storage(or ORM) when something better comes along. And if I have logic in the repository I need to rewrite this logic when I change the repository. If my repository only returns IQueryable and the service does the filtering on the other hand, I will only need to replace the mappings.
For example I recently replaced several of my Linq-To-Sql repositories with EF4 and those where I had stayed true to this principle could replaced in a matter of minutes. Where I had some logic it was a matter of hours instead.
The accepted answer (and upvoted hundreds of time) has a major flaw. I wanted to point this out in the comment but it will just get buried down there in 30 something comments so pointing out here.
I took over an enterprise application which was built that way and my initial reaction was WTH? ViewModels in service layer? I did not want to change the convention because years of development had gone into it so I continued with returning ViewModels. Boy it turned into a nightmare when we started using WPF. We (the team of devs) were always saying: which ViewModel? The real one (the one we wrote for the WPF) or the services one? They were written for a web application and even had IsReadOnly flag to disable edit in the UI. Major, major flaw and all because of one word: ViewModel!!
Before you make the same mistake, here are some more reasons in addition to my story above:
Returning a ViewModel from the service layer is a huge no no. That's like saying:
If you want to use these services you better be using MVVM and here is the ViewModel you need to use. Ouch!
The services are making the assumption they will be displayed in a UI somewhere. What if it is used by a non UI application such as web services or windows services?
That is not even a real ViewModel. A real ViewModel has observability, commands etc. That is just a POCO with a bad name. (See my story above for why names matter.)
The consuming application better be a presentation layer (ViewModels are used by this layer) and it better understand C#. Another Ouch!
Please, don't do that!
Repository layer is implemented to access the database and helps to extend the CRUD operations on the database. Whereas a service layer consists of the business logic of the application and may use the repository layer to implement certain logic involving the database. In an application, it is better to have a separate repository layer and service layer. Having separate repository and service layers make the code more modular and decouple the database from business logic.
Usually a repository is used as scaffolding to populate your entities - a service layer would go out and source a request. It is likely that you would put a repository under your service layer.

Is there any benefit to using single Repository instance for Asp.net Mvc application?

In CarTrackr project, It use some technique that creates only 1 repository instance for all request in Asp.net Mvc website and uses UnityControllerFactory class to manage all repository instanes(send to requested controller).
Is there any benefit to using single repository instance when compare with creating new repository instance every request?
I know, it may improve overall performance. But, Does it cause any transcation problem?
partial Global.asax
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
RegisterDependencies();
}
protected static void RegisterDependencies() {
IUnityContainer container = new UnityContainer();
// Registrations
container.RegisterType<IUserRepository, UserRepository>(new ContextLifetimeManager<IUserRepository>());
container.RegisterType<ICarRepository, CarRepository>(new ContextLifetimeManager<ICarRepository>());
// Set controller factory
ControllerBuilder.Current.SetControllerFactory(
new UnityControllerFactory(container)
);
}
}
partial CarController.cs
[Authorize]
public class CarController : Controller
{
private IUserRepository UserRepository;
private ICarRepository CarRepository;
public CarController(IUserRepository userRepository, ICarRepository carRepository)
{
UserRepository = userRepository;
CarRepository = carRepository;
}
}
Thanks,
Creating a repository instance per request by itself shouldn't cause any performance issue; the repository is often pretty shallow, and when it needs to access data things like connection pooling minimise the cost of establishing actual connections. Object creation is astonishingly cheap, especially for short-lived things like web requests where the object gets collected while still in "generation zero".
As to whether to have a single repository or a repository per instance - that depends on the repository ;-p
The biggest question is: is your repository thread safe? If not: one per request.
Even if it is though; if your repository itself keeps something like a LINQ-to-SQL DataContext (that you synchronize somehow), then you have big problems if you keep this long-term, in particular with the identity manager. You'll quickly use a lot of memory and get stale results. Far form ideal.
With a single repository instance, you will probably also end up with a lot of blocking trying to get thread safety. This can reduce throughput. Conversely, the database itself has good ways of achieving granular locks - which is particularly useful when you consider that often, concurrent requests will be looking at separate tables etc - so no blocking at the database layer. This would be very hard to do just at the repository layer - so you'd probably have to synchronize the entire "fetch" - very bad.
IMO, one per request is fine in most cases. If you want to cache data, do it separately - i.e. not directly on the repository instance.
I think you're misunderstanding whats happening with the ContextLifeTimeManager. By passing the manager into the Register() method your telling Unity to set the caching scope for your repository instance to HttpContext.
It is actually incorrect to say:
It use some technique that creates only 1 repository instance for all request in Asp.net > Mvc website
There is not a repository singleton. Unity is creating one for each request. It sounds like this is actually your desired behavior.
When the manager's scope is set to HttpContext the container looks to HttpContext for an existing instance of the requested type (in this case, your repository). Since the HttpContext is fresh on each request, the container will not have this instance, thus a new one will be created.
When you ask:
Is there any benefit to using single
repository instance when compare with
creating new repository instance every
request?
No.
As far as transaction problems: Threading will def be an issue. The CarRepository appears to be using Linq2Sql or Linq2Entities. Its ctor requires an active datacontext. DataContext is NOT thread safe. If the datacontext is being stored at a scope higher than the current request, there will be problems.
Using the new ContextLifetimeManager());, the lifetime of a repository is limited to one request. This means that evry request each repository is instantiated (if needed) and destroyed once a response has been sent to the client.

Resources