In my app I have lots of scheduled service classes implemented like this:
public FiddleService {
private TaskScheduler scheduler;
private void setupScheduler() {
Runnable task = new Runnable() {
public void run() {
letsFiddle();
}
};
scheduler.scheduleAtFixedRate(task, 10 * 1000);
}
public void letsFiddle() {
...
}
}
At first the structure looked relatively simple, the scheduler will call letsFiddle() every 10 seconds. AOP-transaction wise I thought this should be okay since I used AspectJ mode (instead of JDK proxy).
But I just discovered this is wrong! The annotation was not effective if it’s invoked inside an inner-class.
Yep I only figured this out when strange transaction related behaviour started occuring in my app.
Few trials and errors, and I figured out the best way to implement this is to always separate the task in its own class:
public class FiddleService {
public void letsFiddle() {
...
}
}
public class FiddleServiceScheduler {
private TaskScheduler scheduler;
private FiddleService fiddleService;
private void setupScheduler() {
Runnable task = new Runnable() {
public void run() {
fiddleService.letsFiddle();
}
};
scheduler.scheduleAtFixedRate(task, 10 * 1000);
}
}
This will ensure all construction-related work is done on FiddleService (possibly AOP-tx related stuff) before we invoke its transactional method