[英]How to rollback outer transaction in case of failed inner transaction in but inner transaction should save data Spring
試圖防止內部事務回滾。 如果內部事務響應不成功,則外部事務應回滾,但內部事務應保存數據。
@Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRES_NEW)
private void test1(Account account) throws Exception {
DOA.save(account);
status = test2(account);
if(status!='SUCCESS'){
throw new Exception("api call failed");
}
}
@Transactional(propagation=Propagation.MANDATORY)
private void test2(Account account) {
response //API Call
DOA.save(response);
return response.status;
}
將內部事務方法配置為Propagation.REQUIRES_NEW
,以便無論外部事務方法是否回滾,該方法完成時它將始終提交(即保存數據)。
另外,請確保外部方法不會自我調用內部方法,因為@Transactional
在這種情況下不起作用(請參閱docs中的方法可見性和@Transactional部分)。
它們應該駐留在外部方法調用內部方法的bean的不同bean中:
@Service
public class Service1 {
@Autowired
private Service2 service2;
@Transactional(rollbackFor=Exception.class)
public void test1(Account account) throws Exception {
DOA.save(account);
status = service2.test2(account);
if(status!='SUCCESS'){
throw new Exception("Api call failed");
}
}
}
@Service
public class Service2{
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void test2(Account account) {
response // API Call
DOA.save(response);
return response.status;
}
}
@Transactional
被忽略你Test2
方法和調用單個事務的一部分。
正如Spring文檔所說的,這里有兩件事要考慮-
方法可見性和@Transactional
使用代理時,應僅將@Transactional注釋應用於具有公共可見性的方法。 如果使用@Transactional注釋對受保護的,私有的或程序包可見的方法進行注釋,則不會引發任何錯誤,但是帶注釋的方法不會顯示已配置的事務設置。 如果需要注釋非公共方法,請考慮使用AspectJ(請參見下文)。
代理模式
在代理模式(默認設置)下,僅攔截通過代理傳入的外部方法調用。 這意味着自調用實際上是目標對象中調用目標對象另一個方法的方法,即使調用的方法標記有@Transactional,也不會在運行時導致實際事務。
如果要保存內部方法的數據,則可以選擇為Test2
方法啟動新的Transaction,這樣就不會影響Test1
啟動的現有事務。
但是,即使您公開Test2
從同一個類調用它,也不會在您的情況下啟動新事務。
解決方案-
Propagation.REQUIRES_NEW
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.