views:

109

answers:

2

I was hoping someone could confirm my understanding of transaction behaviour in a Spring service.

Firstly, am I correct in believing that When using TransactionManager, all services which result in persistence to the database must be invoked from within a @Transactional method in order for the update to persist to the db?

Eg, Given the following class:

class MyService
{
   CustomerImporter customerImporter
   CustomerDAO customerDAO

   public void updateCustomer(Customer customer)
   {
       customerDAO.update(customer)
   }

   public List<Customer> importCustomers(String url)
   {
       customerImporter.importCustomers(url);
   }
   return customerDAO.getFromURL(url);
}

If updateCustomer is not @Transactional, will the method have any effect?

Furthermore, If on CustomerImporter the method importCustomers() is marked @Transactional but MyService is not, will the update be persisted to the database?

+2  A: 

Yes, you are correct - you need @Transactional + <tx:annotation-driven /> to make transactions work.

Another way is by using spring's <aop: capabilities in the xml.

As for your second question, it will be executed within the same transaction. Take a look attransaction propagation for how this behaviour is defined on transactional methods.

Bozho
+1  A: 

Firstly, am I correct in believing that When using TransactionManager, all services which result in persistence to the database must be invoked from within a @Transactional method in order for the update to persist to the db?

This is not the case, no. Without the annotation, database updates will be done in a non-transactional fashion, but they'll still happen.

If updateCustomer is not @Transactional, will the method have any effect?

Furthermore, If on CustomerImporter the method importCustomers() is marked @Transactional but MyService is not, will the update be persisted to the database?

Actually, there's no magical association between @Transactional and the DAO. The annotation defines a transaction boundary, and Spring will start/rollback/commit the transaction every time a @Transactional-annotated method is entered or exited.

If you execute a @Transactional-annotated method, and that method then calls another method in another class, and that one calls another one, which eventually does some database work, then you're still inside the transaction. The annotations can go wherever makes sense for you. For example, you can put @Transactional on your MVC controllers if you choose to, it will still work, you're just moving the transaction boundary "up".

skaffman