Search code examples
javaspringhibernatemodel-view-controllertransactional

Number of transactions using @transactional in Spring Mvc


I am a beginner i spring-mvc-hibernate and i have a controller which have many calls to daoimpl methods in my spring mvc which are annotated by @Transactional does it make round trips for every method or does it make a single one?

Code looks like this : Hibernate is used to process all calls

CustomerEntity customerEntity = (CustomerEntity) customerService.getCustomerFromLeadId(id);
AddressEntity resAddressEntity = (AddressEntity) addressService.getResAddress(customerEntity.getSomeId());
AddressEntity offAddressEntity = (AddressEntity) addressService.getOffAddress(customerEntity.getSomeId());
List<KeyContactsEntity> listKeyContacts = keyContactService.getKeyContactOfClient(customerEntity.getSomeId());
List<PropertyEntity> listProperty = propertyService.getListOfProperty(customerEntity.getSomeId()) ;
customerDto = masterService.setEntityValues(customerDto,customerEntity,resAddressEntity,offAddressEntity,listKeyContacts,listProperty);

Solution

  • How the transaction works is simple. If from a component Controller, that is not transactional, you invoke a method from a service, that is transactional, your service method create the transaction, and then when the method it finish, since your controller is not transactional, the transaction is finish and it´s committed.

    So in your case that you´re calling all those services from a non transactional component you create a new transaction for every one of them which is wrong because that´s means that if something goes wrong in the third service you cannot rollback the two previous

    class Controller {
    
        //New transaction
        CustomerEntity customerEntity = (CustomerEntity) customerService.getCustomerFromLeadId(id);
        //New transaction
        AddressEntity resAddressEntity = (AddressEntity) addressService.getResAddress(customerEntity.getSomeId());
        //New transaction
        AddressEntity offAddressEntity = (AddressEntity) addressService.getOffAddress(customerEntity.getSomeId());
        //New transaction / if something goes wrong no rollback for previous transactions
        List<KeyContactsEntity> listKeyContacts = keyContactService.getKeyContactOfClient(customerEntity.getSomeId());
    
    }
    

    If you want group all your service transaction in just one, you need wrapp all of them into a "facade" component with @Transaction

       @Transactional
       class FacadeService {
    
        //New transaction
        CustomerEntity customerEntity = (CustomerEntity) customerService.getCustomerFromLeadId(id);
        //Reuse transaction
        AddressEntity resAddressEntity = (AddressEntity) addressService.getResAddress(customerEntity.getSomeId());
        //Reuse transaction
        AddressEntity offAddressEntity = (AddressEntity) addressService.getOffAddress(customerEntity.getSomeId());
        //Reuse transaction / If something goes wrong rollback of everyting
        List<KeyContactsEntity> listKeyContacts = keyContactService.getKeyContactOfClient(customerEntity.getSomeId());
    
    }