Spring @Transactional包装2个方法

时间:2010-08-18 08:56:09

标签: spring transactions annotations dao

我是春天的新人。我对我的dao方法使用@Transactional注释:

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

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

我已经设置了这样的事务管理器:

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

问题是,当我的客户端代码调用dao.save(..)然后dao.getById(4)时,这些会在两个单独的事务中发生。如何将这2个调用包装在同一个数据库事务中?理想情况下,不要以编程方式进行。

感谢

3 个答案:

答案 0 :(得分:5)

将事务属性放在DAO层中是不好的做法。另外,我不确定为什么你需要getById方法的事务。即使您想使用事务,也需要为save和getById方法指定传播行为为REQUIRES_NEW。

答案 1 :(得分:4)

在这种情况下的良好做法是标记服务方法,它将这两个DAO方法作为@Transactional调用。案件清楚地讨论了here

答案 2 :(得分: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(...);
}

但是,最好的方法是让“save”方法返回一个ID,因为很难事先知道Person将持有哪个ID。