We can easily work around this issue by creating a new class that will execute a given method in a new transaction:
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.function.Supplier;
/**
* Since spring ignores transaction settings for methods within the same class, we need a separate service
* to run isolated transactions which can be called from anywhere simply by supplying the method to execute
*/
@Service
public class TransactionHandlerService {
/**
* Runs the given method in a the same transaction as the caller
*
* @param supplier the method to execute
* @param <T>
* @return the result of the invoked method
*/
@Transactional(propagation = Propagation.REQUIRED)
public <T> T runInSameTransaction(Supplier<T> supplier) {
return supplier.get();
}
/**
* Runs the given method in a separate transaction
*
* @param supplier the method to execute
* @param <T>
* @return the result of the invoked method
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
public <T> T runInNewTransaction(Supplier<T> supplier) {
return supplier.get();
}
}
Then ensure the callers are annotated as @Transactional and simply pass the method to execute as input to our, for example:
transactionHandlerService.runInNewTransaction(() -> myMethod(someInput));
No comments:
Post a Comment
With great power comes great responsibility