【问题标题】:Spring @Transactional wrapping 2 methodsSpring @Transactional 包装 2 种方法
【发布时间】:2011-03-31 10:31:13
【问题描述】:

我是春季新手。我对我的 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) 这些发生在两个单独的事务中。如何将这两个调用包装在同一个数据库事务中?最好不要以编程方式进行。

谢谢

【问题讨论】:

    标签: spring transactions annotations dao


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:
      @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。

      【讨论】:

      • 谢谢。 getById 只是一个例子。
      【解决方案3】:

      在这种情况下,好的做法是将调用这两种 DAO 方法的服务方法标记为@Transactional。此案已明确讨论here。

      【讨论】:

        猜你喜欢
        • 2017-06-18
        • 1970-01-01
        • 2018-02-26
        • 2015-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-21
        • 2019-02-26
        相关资源
        最近更新 更多