1

I have a webapp with a tons of spring mvc controllers. Those controllers interact with a DB with JPA, entities and repositories.

I would like to be sure that when a controller method is handled by spring mvc, all DB changes that append during that method are rollback if any exception is thrown during the process.

Here an example:

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

Controller

@Controller
public class JpaTest {

    @Autowired
    GroupRepository groupRepository;

    @RequestMapping(value = "/{langId}/jpatest", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    @Transactional
    public String test() throws Exception {
        Group group = new Group();
        group.setName("jpaTest");
        groupRepository.save(group);
        throw new Exception("MY EXCEPTION ");
    }
}

I expect the group is not added in the DB !

I hope the @Transactional would make it but not.

I added

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

But no effect. Is there a way to do it simply ?

Or could I encapsulate my dispatcher Servlet to have kind of super transaction management, like we did with jeeves :

protected void doDispatch(final HttpServletRequest request, final HttpServletResponse response) throws Exception {
    JeevesDispatcherServlet.super.doDispatch(request, response);

    TransactionManager.runInTransaction("jeevesDispatchServlet", getWebApplicationContext(),
        TransactionManager.TransactionRequirement.CREATE_ONLY_WHEN_NEEDED,
        TransactionManager.CommitBehavior.ONLY_COMMIT_NEWLY_CREATED_TRANSACTIONS,
        false, new TransactionTask<Void>() {
            @Override
            public Void doInTransaction(TransactionStatus transaction) throws Throwable {
                JeevesDispatcherServlet.super.doDispatch(request, response);

                return null;
            }
        });
}
Neil Stockton
  • 11,383
  • 3
  • 34
  • 29
FlowP
  • 11
  • 3

2 Answers2

1

This is not the best design, but if is needed, you can try with a more specific exception with the throw clause and the rollbackFor attribute of @Transactional.

Take a look at this post.

Community
  • 1
  • 1
angcap
  • 149
  • 2
  • 9
-2

why do you want a transaction for a single insert/save action. If the save fails it will not be saved so there is nothing to rollback

baliman
  • 588
  • 2
  • 8
  • 27