Reputation: 16560
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?
Upvotes: 2
Views: 3706
Reputation: 23226
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 {
}
Upvotes: 4
Reputation: 1549
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>
Upvotes: 0