首页 > 解决方案 > 在 Spring 4.3 中从非事务方法调用 @Transactional 方法

问题描述

我有以下代码:

@Service
public class ItemService {
    ...

    public void addItems(@Nonnull DocumentDTO dto) throws Exception {
        // some code that takes some time to process
        ...

        addItems(dto.getDocId(), items);
    }

    @Transactional
    public void addItems(long docId, @Nonnull List<Item> items) {
        itemDao.addItems(docId, items);
    }
}

第一种方法不是@Transactional,它使用@Transactional 调用第二种方法。SonarLint 工具指出“方法不应调用具有不兼容的“@Transactional”值的同类方法”(https://rules.sonarsource.com/java/RSPEC-2229

但是这段代码在 Spring 4.3.20 中可以正常工作。此规则是否适用于 Spring 4.3.20?

PS 有趣的是,如果我将第二种方法设为私有包,SonarLint 警告就会消失……为什么?

标签: javaspringsonarqubeaopsonarlint

解决方案


但是这段代码在 Spring 4.3.20 中可以正常工作。此规则是否适用于 Spring 4.3.20?

是的。SonarLint 是正确的。自调用不能@Transactional生效。即使在 Spring 5 中它也不会改变。这就是 Spring AOP 的工作方式(请参阅docs)。您的代码很可能有效,因为您在内部开始了另一笔交易itemDao(可能是您在 @Transactional上标记了另一笔交易ItemDao#addItems())。

如果我将第二种方法设为包私有,SonarLint 警告就会消失……为什么?

不知道为什么。也许这是一个错误。正如这条规则@Transactional中提到的,在私有方法中标记时应该给你警告。


推荐阅读