Wednesday, April 27, 2011

Enterprise Application's Logical Layers and where to manage Transactions

Recently I came across an application which manage transaction's at Dao layer that means there is no proper transaction management and if an exception occurs during runtime will leave inappropriate data in database.

Consider this simple Architectural layers

Brief description of each block starting from the bottom.

DB1 .. DBn → Databases, an application sometimes refers to multiple databases and simple application has one.

Dao Layer →  Encapsulates logic to add, update, delete and read data from Databases using JPA, Hibernate or JDBC.

Entity/Dto → Simple Pojo classes which encapsulate database entities

WebServices Client → Another Integration Layers like Dao which communicates with other systems via SOAP, JMS etc.

Service Layer → This layer contains business logic which encapsulate the data (Dao & Webservices client) they operate on and provide hardened interfaces as the only way to access their functionality. This approach reduces side effects and allows services to evolve at their own pace without impacting the other components of the overall system.

UI/Controller → If you use any MVC framework then this layer contains Controller or Action classes which directly serve browser requests and delegates all operations to Service Layers Classes i.e. they don't have any business logic in them.

Web Services → This layer contains Web Services or External facing API's if you plan to expose some functionality for other systems to integrate via SOAP, REST, RMI etc. Also this should just delegate all functionality to Service Layers classes, Main reason we have this extra layer to expose some functionality is to have its own space to evolve with different revisions without impacting the overall system, this separation is very important if you system needs to involve over time and external changes.

Coming back to the original topic as which layer to manage transactions, also you can clearly see in the Architecture diagram above that Service Layer lies at the heart of the system exposing business logic to UI and other API's and hence that's where Transactions should be manage.

Checkout this sample transaction management code

* @author intesar
public class UserServiceImpl implements UserService {

    * Dummy Use Case # 33
    * Admin can select multiple users on UI page and update the active status and then saves
    * updates multiple users in a single transactions
    * @param users
   @Transactional(propagation = Propagation.REQUIRED)
   public void updateUsers(List<User> users){
       for ( User user: users ) {
   protected UserDao userDao;
   protected static final Log log = LogFactory.getLog(UserServiceImpl.class);

As you can see in the above code snippet updateUsers(..) method part of Service Layer class,  updates multiple users in a single operation and if any user update fails then entire operation rollsback. However this not possible if we are managing transactions at Dao layer.

I am using Spring framework to manage my transactions though you can use JEE or any other framework.


Javin Paul said...

I didn't get the point completely , to me most of the transaction completes when data successfully entered into database, so either you could have synchronous database insertion or asynchronous database insertion , in case of asynchronous database insertion there is chance of data loss if data stays in temp memory and application dies. What's your opinion ?

Why String is immutable in Java

Don Stevo said...

I think the point stated here is:

If your service method calls several DAO methods, when you put your transaction management in the DAO layer each previous DAO method will be comitted, even if a subsequent DAO method throws an exception. Possibly erronous data will remain in the database this way.

If your transaction management is around your Service method, when one of the DAO methods throws an Exception your entire Service call will be rollbacked and no modified data will remain in the database.

jbaris said...
This comment has been removed by the author.
jbaris said...

You are forgetting a BusinessObject layer between the Services layer and the DAO layer. All the business logic must be inside this layer, and its methods can be transactional.
The adventage of having a BO layer is that other technologies than WS (eg JMS) can access to the BO logic, and you can make transactional multiple DAO calls.
In brief, having a BO layer have to adventages:
1) solves your problem of transactinality
2) makes your app more extensible (for other communication technologies)

Best regards