gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 14:19:28 24 4
gpt4 key购买 nike

我在结合 Spring 回滚 Hibernate 更新时遇到问题。

我有以下类(class):

@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");
}
}

该接口(interface)未使用任何 @Transactional 注释进行标记。 saveDocument() 方法是直接从我的 Controller 调用的,因此我希望使用该方法的 @Transactional 配置,特别是 rollbackFor 参数。然而,当抛出 DocumentServiceException 时,不会回滚任何内容(即 getDao().saveOrUpdate(document) 被保留)。出于测试目的,我在 storeDocument 方法中添加了“抛出新的 IOException”。希望任何人都可以帮助我如何使其正常工作,我将不胜感激。

最佳答案

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

  2. 当您说直接调用方法时,我假设您的接口(interface)是@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 上下文中的 Controller (并且没有 Autowiring 依赖项,如其服务)以及 applicationContext 中的服务/daos。

来自 applicationContext 的服务随后被事务化。

关于java - Spring @Transactional rollbackFor 不适用于在代理对象外部调用的方法的检查异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27358031/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com