'How to rollback child transaction if any exception in parent transaction?
I have two transaction manager for two database. I need to persist same data into both databases. If one transaction failed, other one need rollback. I have done like below
public interface DataService {
void saveData();
}
@Service
public class DataServiceImpl implements DataService {
@Autowired
private DataRepository dataRepository;
@Autowired
private OrDataRepository orDataRepository;
@Autowired
@Qualifier("orService")
private OrService orDataServiceImpl;
@Override
@Transactional(transactionManager = "transactionManager", rollbackFor = {RuntimeException.class})
public void saveData() {
Data data = new Data();
data.setCompKey(UUID.randomUUID().toString().substring(1,5));
data.setName("data");
dataRepository.save(data);
orDataServiceImpl.save();
//throw new RuntimeException("");
}
}
public interface OrService {
void save();
}
@Service("orService")
public class OrDataServiceImpl implements OrService {
@Autowired
private OrDataRepository orDataRepository;
@Override
@Transactional(rollbackFor = {RuntimeException.class})
public void save() {
OrData data = new OrData();
data.setCompKey(UUID.randomUUID().toString().substring(1,5));
data.setName("ordata");
orDataRepository.save(data);
}
}
I have two transaction manager (entityManager & orEntityManager) for two different DB.
If any exception in OrDataServiceImpl save method, data is not getting persisted in both DB. But if any exception in DataServiceImpl saveData method, data is getting persisted into OrData table.
I want to rollback the data from both DB if any exception.
chainedTransactionManager is deprecated. So can't use. atomikos and bitronix also can't use due to some restrictions. Kindly suggest better way to achieve distributed transation
Solution 1:[1]
The code need to be refactored, edit the DataServiceImpl.save() method.
Comment the orDataServiceImpl.save() line
public void saveData() { Data data = new Data(); data.setCompKey(UUID.randomUUID().toString().substring(1,5)); data.setName("data"); dataRepository.save(data); //orDataServiceImpl.save(); //throw new RuntimeException(""); }Refactor/Edit the OrDataService Interface
public interface OrDataService { void save(String uuid); void delete(String uuid); //will be use for compensating transaction}
Update the OrDataServiceImpl class to implement above interface
Write new orchestration Method and use compensating transaction to rollback
pseudo code
call OrDataServiceImpl.save()- if step#1 was success
-
-> DataServiceImpl.saveData() -
if Exception at step#3, -
->OrDataServiceImpl.delete() [//to rollback] - else if, Exception at step#1 //do nothing
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | kus |
