0
votes

I have a Service class like below:

@Service("MyService")
public class MyService {
    @Autowired
    MyDao dao;

    public void process() {
        getFromDao();
        // getMoreFromDao();
        // process();
        // if all good, then
        doStuff();
    }

    public void getFromDao() {
        // do some stuff
        dao.getData();
    }

    @Transactional(transactionManager="simpleDatasourceTxMgr", propagation=Propagation.REQUIRED)
    public void doStuff() {
        dao.saveData(1);
        dao.saveData(2);
        dao.saveData(3);
   }
}

The DAO called is:

@Repository
public class MyDao {

    @Autowired
    @Qualifier("myjdbcTemplate")
    NamedParameterJdbcTemplate jdbcTemplate;

     public void saveData(obj a) {
        jdbcTemplate.execute("Query", ...);
    }
}

I want my doStuff() method in the service class to run within a transaction and rollback everything if there is an exception in the saveData() method. But this is not running in transaction.

If I add @Transaction to a DAO method looks like it runs in separate transaction. Is this correct?

Update: I have added a process() method to my Service and I call getFromDao() and doStuff() from process(). process() is called from the controller. So looks like if I make the service class @Transactional, then everything executes within a transaction. But I don't want getFromDao() to execute in transaction.

We use just JDBC and no Hibernate.

1
It should do everything in a unique transaction. How do you know it doesn't? Does myjdbcTemplate use the same DataSource as simpleDatasourceTxMgr? How are these beans defined?JB Nizet
@JBNizet Updated above. Also looks like spring do not call transactional advice if the method is called internally..kriver
No. Transaction management is based on AOP. You need to call the bean from the outside for the transactional interceptor to be able to intercept the call and start a transaction. This is well explained in the documentation. I'm not sure why you wouldn't want getFromDao() to be part of the transaction.JB Nizet
@JBNizet getFromDao() just does a few select queries to few different tables. So isn't it unnecessary overhead to have that as part of transaction?kriver
@kriver I don't know why everyone thinks having a transaction means overhead. Reading doesn't lock either. You're preoptimizing based on incorrect assumptions.JB Nizet

1 Answers

1
votes

You can place the @Transactional annotation before an interface definition, a method on an interface, a class definition, or a public method on a class. However, the mere presence of the @Transactional annotation is not enough to activate the transactional behavior. The @Transactional annotation is simply metadata that can be consumed by some runtime infrastructure that is @Transactional-aware and that can use the metadata to configure the appropriate beans with transactional behavior. In the preceding example, the element switches on the transactional behavior.

Or if you want annotations you can enable it with

It is not sufficient to tell you simply to annotate your classes with the @Transactional annotation, add @EnableTransactionManagement to your configuration, and then expect you to understand how it all works. This section explains the inner workings of the Spring Framework’s declarative transaction infrastructure in the event of transaction-related issues.

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html