I have a project where the pseudo code is like this
BundleService:
@Transactional(rollbackFor = Exception.class)
public transferBundleToDestination() {
//do some validation checks here and then create new bundle
Bundle b = new Bundle();
dao.save(b);
folderService.createFoldersInBundle(b.getFolders());
}
FolderService
@Transactional(propagation = Propagation.MANDATORY) //I set this because if this method throws an exception it needs to roll back the bundle created in transferBundleToDestination too
public void createFoldersInBundle(bundleWithFolderInfo) {
foreach(folder in bundleWithFolderInfo) {
//do some validation here, if error then throw exception to rollback bundle created in previous step
Folder f = new Folder();
dao.save(f);
productService.createProductsInFolder(folder.getProducts())
}
ProductService:
@Transactional(propagation = Propagation.MANDATORY) //I set this because if this method throws an exception it needs to roll back the transferBundleToDestination too
public void createProductsInFolder(folderWithProducts) {
foreach(product in folderWithProducts) {
//do some validation here, if error then throw exception to rollback bundle and folder created in previous steps
Product p = new Product();
dao.save(p);
}
My issue is that for each bundle sometimes there are lots of folders and inside the folders there are a lot of products. So I would like to run the createProductsInFolder asynchronously. However when I marked createProductsInFolder method with @Async (and set up the @EnableAsync and configurations) to return a CompletableFuture it doesn't work and complains about no transaction propogated.
org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
How should I be speeding this up? Is it possible to use @Async here??
Thanks