Suppose I use 2 threads in a transaction to speed up processing. If the userDao.addOrg() method throws a RuntimeException, the transaction will not be rolled back and the error will not be caught. What should I do? Is that right?
ExecutorService executorService = Executors.newCachedThreadPool();
@Transactional(rollbackFor=Throwable.class)
public void add(){
CountDownLatch cdl = new CountDownLatch(2);
executorService.submit(new Runnable() {
public void run() {
userDao.addOrg(); //抛出RuntimeException异常
cdl.countDown();
}
});
executorService.submit(new Runnable() {
public void run() {
userDao.addSystem();
cdl.countDown();
}
});
cdl.wait(10,TimeUnit.SECONDS);
}
世界只因有你2017-06-12 09:28:37
@Transactional can only control single-threaded transactions, so child threads are not controlled by transactions on the add method. You can start a new transaction on the method called by the child thread and roll back.
Enable child threads to call transaction-controlled methods:
executorService.submit(new Runnable() {
public void run() {
addOperation.addMethod();
}
});
@Component
class AddOperation{
@Transactional
public addMethod(){
userDao.addOrg(); //抛出RuntimeException异常
cdl.countDown();
}
}
Note that @Transactional is implemented through proxy, so addMethod must be placed in the new class AddOperation and cannot be placed in the class where the add method is located.