程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

Spring @Transactional rollbackFor 不适用于调用外部代理对象的方法的已检查异常

发布于2023-06-03 15:51     阅读(1100)     评论(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”。希望任何人都可以帮助我解决这个问题,我将不胜感激。


解决方案


  1. @Transactional 注释已正确放置。您不必在接口级别设置它,因为它不会自动继承(如果您的具体类实现两个具有冲突事务设置的接口怎么办)。

  2. 当您说直接调用该方法时,我假设您的接口是 @Autowired 而不是具体实现。

  3. 在您的服务方法中放置一个断点,并检查您的堆栈跟踪中是否有 TransactionInterceptor 条目。如果你没有,那么你的事务管理配置是错误的,你根本就没有使用 Spring 事务管理。

丹尼斯更新

  1. 也许还有一件事可以帮助其他人:

    我的 applicationContext 中有 tx:annotation-driven。applicationContext 包含对所有 bean 的组件扫描(无过滤器)。

    但是,dispatcherServlet 上下文还包含对所有 bean 的组件扫描(遗留代码,不要射击信使)。所以基本上我有我所有 bean 的副本,因为它们在两种情况下都被扫描过。

    而且因为在 dispatcherServlet 上下文中创建的 bean 不包含 tx:annotation-driven 元素,所以在 dispatcherServlet 上下文中的服务 bean 不是事务性的。

  2. 我不得不将 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黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

6 0
收藏该文
已收藏

评论内容:(最多支持255个字符)