Calling @Transactional method from non-transactional method in Spring 4.3

serg kunz picture serg kunz · Feb 7, 2019 · Viewed 10.2k times · Source

I have the following code:

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

The first method is not @Transactional and it calls the second one with @Transactional. SonarLint tool states that "Methods should not call same-class methods with incompatible "@Transactional" values" (https://rules.sonarsource.com/java/RSPEC-2229)

But this code works correctly in Spring 4.3.20. Is this rule actual for Spring 4.3.20?

P.S. Interesting, if I make the second method as package-private, the SonarLint warning disappears... Why?

Answer

Ken Chan picture Ken Chan · Feb 7, 2019

But this code works correctly in Spring 4.3.20. Is this rule actual for Spring 4.3.20?

Yes. SonarLint is correct. Self-invocation cannot make @Transactional to take effect. It does not change even in Spring 5. That is how Spring AOP works (refer to docs). Your codes works most probably because you start another transaction inside itemDao (May be you have another @Transactional marked on ItemDao#addItems()).

if I make the second method as package-private, the SonarLint warning disappears... Why?

Don't know why. Maybe it is a bug. As mentioned in this rule , it should give you warning when mark @Transactional in private method.