简体   繁体   English

如果在控制器中引发异常,则Spring JPA回滚事务

[英]Spring JPA rollback transaction if Exception thrown in controller

I have a webapp with a tons of spring mvc controllers. 我有一个带有大量Spring MVC控制器的Webapp。 Those controllers interact with a DB with JPA, entities and repositories. 这些控制器与具有JPA,实体和存储库的数据库进行交互。

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. 我想确定的是,当控制器方法由spring mvc处理时,如果在此过程中引发任何异常,则在该方法期间附加的所有数据库更改都将回滚。

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. 我希望@Transactional能够成功,但不能成功。

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 : 或者我可以封装我的调度程序Servlet以进行某种超级事务管理,就像我们对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;
            }
        });
}

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 . 这不是最佳的设计,但是如果需要,可以尝试使用带有throw异常和@TransactionalrollbackFor属性的更具体的异常。

Take a look at this post . 看一下这篇文章

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 如果保存失败,将不会保存,因此没有回滚的内容

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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