【问题标题】:Nested @Transactional annotation behaviour on Spring Data JPASpring Data JPA 上的嵌套 @Transactional 注释行为
【发布时间】:2015-04-16 19:03:58
【问题描述】:

我有一个实体User、一个Repository/Dao 类UserDao(使用Spring Data JPA)和一个Service 类UserService,方法addUser 注释为@Transactional

@Service
public class UserService {

  @Autowired
  private UserDao userDao;

  @Transactional
  public void addUser() throws Exception {

    User user = new User();
    user.setUsername("aaa");

    // Save the user, but since this method have the @Transactional
    // annotation it should not be committed....
    userDao.save(user);

    // Forcing an error here I expected that the previous operation
    // were rolled back.. Instead the user is saved in the db.
    if ("".equals("")) {
      throw new Exception("something fails");
    }

    // Other operations (never executed in this example)
    user.setUsername("bbb");
    userDao.save(user);

    return;
  } // method addUser

} // class UserService

UserDao 就是这样:

@Transactional
public interface UserDao extends CrudRepository<User, Long> { }

阅读 Spring Data JPA documentation 和关于同一参数的其他问题(12)我的期望是,如果发生错误,标记为 @Transactional 的方法中的每个操作都将被回滚。 .

我做错了什么? 如果发生错误,有没有办法回滚上一个示例中的保存操作?

【问题讨论】:

标签: java spring jpa spring-data spring-data-jpa


【解决方案1】:

您的理解是正确的,但是自动回滚只发生在运行时,未经检查的异常。

因此,假设您的事务管理器配置正确,要在非运行时回滚,检查异常添加 rollbackFor 属性到您的事务注释:

@Transactional(rollbackFor=Exception.class)
public void addUser() throws Exception {

}

【讨论】:

  • 是的!...谢谢,我将Exception 更改为RuntimeException,现在一切正常。当这个解释得很好时,你有一些参考吗?
  • 这是什么原因?为什么只有未经检查的异常会导致回滚?
【解决方案2】:

您需要将内容添加到您的 Xml 配置文件中。您需要添加事务管理器。

 <tx:annotation-driven transaction-manager="txMgrDataSource" />

<!-- Creating TransactionManager Bean, since JDBC we are creating of type
    DataSourceTransactionManager -->
<bean id="txMgrDataSource"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="DataSource" />
</bean>

假设你的数据源是:

<bean id="DataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="####" />
    <property name="url"
              value="jdbc:sqlConnection" />
    <property name="username" ref="user" />
    <property name="password" ref="pass" />

</bean>

【讨论】:

  • 谢谢,我使用的是默认配置的 Spring Boot(我没有任何配置文件)。
  • 好吧,我还没有使用spring boot。但据我所知,他只是提供嵌入式容器(Tomcat等)。无论如何祝你好运:)
猜你喜欢
  • 2022-01-02
  • 1970-01-01
  • 2021-12-24
  • 2013-01-06
  • 2018-06-27
  • 1970-01-01
  • 2012-03-08
  • 1970-01-01
相关资源
最近更新 更多