发布于2023-06-03 15:51 阅读(1165) 评论(0) 点赞(6) 收藏(4)
我在结合 Spring 回滚 Hibernate 更新时遇到问题。
我有以下课程:
@Service
@Transactional(readOnly = true)
public class DocumentServiceImpl extends AbstractGenericService<Document, IDocumentDao> implements DocumentService {
@Override
@Transactional(readOnly=false, rollbackFor = DocumentServiceException.class)
public void saveDocument(final DocumentForm form, final BindingResult result, final CustomUserContext userContext) throws DocumentServiceException {
Document document = locateDocument(form, userContext);
if (!result.hasErrors()) {
try {
updateDocumentCategories(form, document);
storeDocument(document, form.getDocumentId(), form.getFile());
solrService.addDocument(document);
} catch (IOException e) {
result.reject("error.uploading.file");
throw new DocumentServiceException("Error trying to copy the uploaded file to its final destination", e);
} catch (SolrServerException e) {
result.reject("error.uploading.file.solr");
throw new DocumentServiceException("Solr had an error parsing your uploaded file", e);
}
}
}
@Override
@Transactional(readOnly = false, rollbackFor = IOException.class)
public void storeDocument(Document document, String documentId, CommonsMultipartFile uploadedFile) throws IOException {
getDao().saveOrUpdate(document);
if (StringUtils.isBlank(documentId)) {
File newFile = documentLocator.createFile(document);
uploadedFile.transferTo(newFile);
// Todo: TEST FOR ROLLBACK ON FILE I/O EXCEPTION
throw new IOException("this is a test");
}
}
该接口未标记任何 @Transactional 注释。saveDocument() 方法是直接从我的控制器调用的,因此我希望使用该方法的 @Transactional 配置,尤其是 rollbackFor 参数。但是,当抛出 DocumentServiceException 时,不会回滚任何内容(即 getDao().saveOrUpdate(document) 被保留)。出于测试目的,我在 storeDocument 方法中添加了“throw new IOException”。希望任何人都可以帮助我解决这个问题,我将不胜感激。
@Transactional 注释已正确放置。您不必在接口级别设置它,因为它不会自动继承(如果您的具体类实现两个具有冲突事务设置的接口怎么办)。
当您说直接调用该方法时,我假设您的接口是 @Autowired 而不是具体实现。
在您的服务方法中放置一个断点,并检查您的堆栈跟踪中是否有 TransactionInterceptor 条目。如果你没有,那么你的事务管理配置是错误的,你根本就没有使用 Spring 事务管理。
也许还有一件事可以帮助其他人:
我的 applicationContext 中有 tx:annotation-driven。applicationContext 包含对所有 bean 的组件扫描(无过滤器)。
但是,dispatcherServlet 上下文还包含对所有 bean 的组件扫描(遗留代码,不要射击信使)。所以基本上我有我所有 bean 的副本,因为它们在两种情况下都被扫描过。
而且因为在 dispatcherServlet 上下文中创建的 bean 不包含 tx:annotation-driven 元素,所以在 dispatcherServlet 上下文中的服务 bean 不是事务性的。
我不得不将 dispatcherServlet 上下文中的组件扫描更改为:
<context:component-scan base-package="your/base/package" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
因此,它只会实例化调度程序 servlet 上下文中的控制器(并且没有自动装配的依赖项,如它的服务),以及 applicationContext 中的服务/daos。
来自 applicationContext 的服务随后被事务化。
作者:黑洞官方问答小能手
链接:http://www.javaheidong.com/blog/article/673979/41e53b63bc64feda8305/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!