当前位置: 首页 > 知识库问答 >
问题:

Spring@transactional rollback,用于在代理对象之外调用的方法的检查异常

莘俊能
2023-03-14
@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");
        }
    }

共有1个答案

钱焕
2023-03-14

>

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

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

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

    >

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

    我在ApplicationContext中使用了TX:Annotation驱动。applicationContext包含对所有bean的组件扫描(没有过滤器)。

    但是,dispatcherServlet上下文还包含对所有bean的组件扫描(遗留代码,不要拍摄messenger)。所以基本上我有一个我所有的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> 
    

    因此,它将只实例化dispatcher servlet上下文中的控制器(没有autowired依赖项,比如它的服务),以及ApplicationContext中的服务/DAO。

    然后,来自applicationContext的服务被事务化。

  •  类似资料:
    • 我使用的是Spring3.2.0。根据这个答案,我在我的注释控制器中有相同的方法,它实现接口, Spring配置包括, 当文件大小超过时,应该调用前面的方法,它应该自动处理异常,但它根本不会发生。即使发生异常,也不会调用方法。处理此异常的方法是什么?我是不是漏掉了什么? 在任何情况下都不会调用方法。 一般来说,如果可能的话,我希望每个控制器基(控制器级别)处理此异常。为此,一个注释方法应该只对该特

    • 7.2.3 对象方法的调用 一旦创建了对象,就可以通过向对象发消息来调用对象的方法。消息的格式如下: <对象>.<方法>(<实参>) 其含义是请求<对象>执行<方法>,方法定义中列出的形式参数由<实参>提供。 例如,接着前面的例子执行如下语句: >>> p1.whatName() My name is Lucy >>> p2.whatName() My name is Tom >>> p2.ho

    • 问题内容: 我有一个非常简单的Java类,它使用输入验证以及明显的void set()和String get()方法来有效地装饰Map。 我希望能够有效地调用这些方法并从JVM外部处理返回值和异常,但仍在同一台计算机上 更新:我想到的调用者不是另一个JVM; 谢谢@戴夫雷 我的实施注意事项很典型 性能 易于实施和维护(简单吗?) 可靠性 灵活性(例如,我可以从远程计算机上拨打电话等) 有“正确的方

    • 我有一个spring组件bean,它包含一个由@HystrixCommand和FallbackMethod定义的方法methodA。bean有另一个方法methodB通过CompletableFuture.SupplyAsync(...)调用methodA。我预计Hystrix javanica会在methodA上编织方面,但是当我调试它时,我没有看到Hystrix方面被编织。 下面是一些主要的s