I've found an interesting bug, that if the bean has reference to itself and some method marked with @Scheduled
annotation, then this method is executed without any aspects, including @Transactional
.
Like in this case:
@Service
public class ServiceWithIssue {
@Autowired
private ServiceWithIssue serviceWithIssue;
@Transactional
@Scheduled(initialDelay = 10, fixedDelay = 100000)
public void runTask() {
if (!TransactionSynchronizationManager.isActualTransactionActive()) {
throw new RuntimeException("ServiceWithIssue not in transaction!");
}
System.out.println("ServiceWithIssue is in transaction!");
}
}
In the above example exception will be thrown.
As a workaround to fix this, we can add @Lazy
annotation to our circular dependency.
After a brief debug I think the problem is somewhere in class AbstractAutoProxyCreator
, but can't guarantee this.
Reproduced in org.springframework.boot:spring-boot-starter-parent:2.1.8.RELEASE
A test project to quickly reproduce the problem: test-project.zip
Comment From: snicoll
As a workaround to fix this, we can add @Lazy annotation to our circular dependency.
That's not really a workaround. A circular dependency should not happen in the first place. If you insist of injecting a bean into itself, lazy resolution, or using ObjectProvider
is the only way out.