简体   繁体   中英

Nested @Transactional annotation behaviour on Spring Data JPA

I have an entity User , a Repository/Dao class UserDao (using Spring Data JPA ) and a Service class UserService with a method addUser annotated as @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

The UserDao is simply this:

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

Reading the Spring Data JPA documentation and other questions on the same argument ( 1 , 2 ) my expectations were that each operations inside a method marked with @Transactional will be rolled back if some error occurs..

What am I doing wrong? Is there a way for rollback the save operation in the previous example if an error occurs?

Your understanding is correct however automatic rollback only occurs for runtime, unchecked exceptions.

So, assuming your transaction manager is configured correctly, to rollback on a non-runtime, checked exception add the rollbackFor attribute to your transactional annotation:

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

}

You need to add things to your Xml configuration file.. you need to add trnasaction manager.

 <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>

Assuming your data source is:

<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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM