嘿伙计们,我已经在一个项目上工作了一段时间,其中包含以下组件:
我正在使用Spring的EntityManager魔术......但是我在处理我的动作中的事务时遇到了问题。例如,我在我的类中的几个方法中设置了持久化对象的值,如果rollback
方法发现验证错误,我希望能够validate
,或者commit
这些否则改变。我已经花了很长时间阅读一半的互联网进行全面的解释。不幸的是,没有完整的例子(至少类似于我的堆栈)。
我在邮件列表上偶然发现了这个帖子:@Transactional Spring Annotation in a Struts2 Action does not work。我正在链接的消息似乎有一个非常简单和直接的解决方案,使用TransactionInterceptor
将会发挥它的作用......问题是我找不到有关此拦截器的有用信息。
此处的任何人都有使用此技术的经验,并且可以在Struts2操作中如何使用Spring事务提供一些提示和一两个链接?
谢谢!
- 编辑1 -
如果您有兴趣,我已经设置了一个测试项目,只需download the file并尝试一下(或检查它)。谢谢!
答案 0 :(得分:4)
通常,控制器/操作/支持bean / etc不处理事务。操作是后端代码的Web部分 - 它们应该只关注收集请求数据和发送响应数据。逻辑本身(包括数据库访问)应该在另一层中完成。例如。服务层。因此,您创建另一个bean,将其注入操作中,并使其完成工作 - userService.register(user)
。然后在服务层上配置事务应该是微不足道的,因为它在spring文档和无数的例子中都有:
<tx:annotation-driven />
和@Transactional
(顺便说一句,请确保您现在拥有<tx:..>
,这可能会导致问题。即使它有效,这也不会使我对该服务的建议失效层)
答案 1 :(得分:1)
我不喜欢回答我自己的问题,但是因为我很久以前解决了 ...我认为我应该分享知识(或者在这种情况下缺乏......)。 / p>
我用来了解Struts 2和Spring-JPA-Hibernate的书,在声明服务类之前添加了@Transactional
注释。这是非常错误的,因为所有方法(包括那些只从数据库中检索内容的方法)都在可提交的事务中。长话短说,如果发生异常,一切都会被提交。
感谢Steven和Quaternion也花时间回答我的问题。
答案 2 :(得分:0)
根据您的问题,这是我对您的问题的理解。
您希望在事务中包装操作调用。如果validate方法记录验证错误,则需要回滚事务。据推测,您还希望在发生错误时回滚。
<强>解决方案强>
创建一个拦截器:
您可能希望在堆栈的早期定义此拦截器。我不知道任何预先构建的拦截器(尽管可能有一些),但它应该相当容易组装。
<强>更新强>
我不使用Spring,因此我无法说明JPA事务支持如何在那里工作,但您可以处理EntityManager的事务,如:
try {
entityManager.getTransaction().begin();
// do your thing
entityManager.getTransaction().commit();
} catch (Exception e) {
entityManager.getTransaction().rollback();
throw new PersistenceException(e);
}
这只是一个粗略的例子,但它应该说明一点。