user486480
user486480

Reputation: 183

Coordinating transactions across multiple Daos using Spring JdbcTemplate

I have an architecture that includes a service layer, in which each service class may be injected with one or more dao classes.

I understand how to create and execute a transaction in the daos that extend JdbcDaoSupport. However, I would like to have a higher level control of transactions in the service layer and have a transaction span multiple calls across multiple daos.

public class JdbcUserAccountDao extends JdbcDaoSupport implements UserAccountDao {
    private TransactionTemplate transactionTemplate;

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    @Override
    public void changeUserDetails(final String someString) throws Exception {        

        transactionTemplate.execute(new TransactionCallbackWithoutResult() {

        @Override
        protected void doInTransactionWithoutResult(TransactionStatus status)  {
            try { 
                getJdbcTemplate().update(some table);
                getJdbcTemplate().update(some other table);
            }   
            catch (Exception ex) {
                status.setRollbackOnly();                    
                throw new RuntimeException(ex);
            }
        }
    });
}

Spring context snippet:

<bean id="userAccountDao" class="com.xxx.api.dao.jdbc.JdbcUserAccountDao">
    <property name="dataSource" ref="dataSource"/>
    <property name="transactionTemplate" ref="txTemplate"/>
</bean>

<bean id="txTemplate" class="org.springframework.transaction.support.TransactionTemplate">
    <property name="transactionManager" ref="transactionManager"/>
</bean>

One level up the hierarchy, the service class:

public class UserServiceImpl implements UserService {
    private UserAccountDao userAccountDao;
    private SomeOtherDao someOtherDao;

    public void setUserAccountDao(UserAccountDao userAccountDao) {
        this.userAccountDao = userAccountDao;
    }

    public void setSomeOtherDao (SomeOtherDao someOtherDao ) {
        this.someOtherDao = someOtherDao ;
    }

    public void changeUserAndSomeOtherStuff(String details) {

        // Would like transaction to start here ...

        userAccountDao.changeUserDetails(details);
        someOtherDao.changeSomethingElse(details);

        // ... and end here.
    }
}

The service layer bean is, naturally, injected with both Daos.

<bean id="userService" class="com.xxx.api.service.impl.UserServiceImpl">
    <property name="userAccountDao" ref="userAccountDao"/>
    <property name="someOtherDao" ref="someOtherDao"/>
</bean>

I would like to start and end the transaction in my service layer and span calls to different Daos. Is this possible? Thanks for any help.

Upvotes: 0

Views: 980

Answers (1)

Angelo Immediata
Angelo Immediata

Reputation: 6944

If I understood good your question, well i would set the transaction isolation propagation to Propagation.REQUIRED.

For example, in my service I wrote (but note I used the annotation):

@Transactional(propagation=Propagation.REQUIRED)
public void save(T t) throws Exception {
    try {

        dao.save(t);
    } catch (Exception e) {

        logger.fatal("Errore nel salvataggio dell'entità di tipo "
                + t.getClass().getName(), e);
        throw e;
    }
}

I hope this helps

Angelo

Upvotes: 1

Related Questions