4

I'm a Spring newby. I use the @Transactional annotation for my dao methods:

@Transactional
public Person getById(long id) {
    return new Person(jdbcTemplate.queryForMap(...));
}

@Transactional
public void save(Person person) {
    jdbcTemplate.update(...);
}

and I've set up the transaction manager like this:

<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

The problem is that when my client code calls dao.save(..) and then dao.getById(4) these happen in two separate transactions. How is it possible to wrap those 2 calls in the same database transaction? Ideally without doing it in a programmatic way.

thanks

cherouvim
  • 31,725
  • 15
  • 104
  • 153

3 Answers3

5

It is bad practice to put transactional attributes in DAO layer. Also, I am not sure why do you require transaction for getById method. Even if you want to use transaction then you need to specify propagation behaviour as REQUIRES_NEW for save and getById method.

Rakesh Goyal
  • 3,117
  • 8
  • 39
  • 69
4

Good practice in this case would be marking service method which invokes both these DAO methods as @Transactional. The case was clearly discussed here.

Community
  • 1
  • 1
Vadim Fedorov
  • 463
  • 5
  • 10
4
@Transactional(propagation = REQUIRES_NEW, readOnly = false)
public Person saveAndGetById(Person person, long id) {
    save(person);
    return getById(id);
}

@Transactional(propagation = REQUIRED)
public Person getById(long id) {
    return new Person(jdbcTemplate.queryForMap(...));
}

@Transactional(propagation = REQUIRED, readOnly = false)
public void save(Person person) {
    jdbcTemplate.update(...);
}

However, the best thing would be to have the "save" method return an ID, because it is hard to know beforehand which ID the Person will have once persisted.

Pierre Gardin
  • 684
  • 1
  • 8
  • 23