我有兩個物體:
物體A:
private Long idA;
物體B:
private Long idB;
private Long fkA;
我的微服務只能保存、修改或洗掉 B 物體:
存盤庫:
@Repository
public interface BRepository extends CrudRepository<B, Long>{
}
Feign 外部服務:
@FeignClient(value = "aExtClient", url = "${A_EXT_MS_URL}")
public interface AExtRemoteService {
@DeleteMapping(path = "/a/{idA}", produces = MediaType.APPLICATION_JSON_VALUE)
public Esito deleteA(@PathVariable(name = "idA") Long idA);
}
服務實作:
@Component
@Transactional(rollbackFor = BusinessServiceException.class)
public class BServiceImpl implements BService {
@Autowired
private BRepository bRepository;
@Autowired
private AExtRemoteService aExtRemoteService;
@Override
public void deleteB(B b) {
Long idA = b.getFkA();
bRepository.delete(b); //marker
if(idA != null) {
aExtRemoteService.deleteA(idA);
}
}
}
外部服務只能保存、修改或洗掉 A 物體:
控制器:
@RestController
@RequestMapping("/a")
@CrossOrigin(origins = "${mocks.allowedCrossOrigins:*}")
public class AServiceMockController {
@Autowired
private AMockService aMockService;
@DeleteMapping(value = {
"/{idA}" }, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody ResponseEntity<Result> deleteA(@PathVariable(name = "idA") Long idA) {
Result result = new Result();
aMockService.deleteA(idA);
result.setResult(true);
result.setCod(String.valueOf(HttpStatus.OK.value()));
result.setMess(HttpStatus.OK.name());
return new ResponseEntity<>(result, HttpStatus.OK);
}
}
服務:
@Service
public class AMockService {
private final ARepository aRepository;
@Autowired
public AMockService(ARepository aRepository) {
this.aRepository = aRepository;
}
public void deleteA(Long idA) {
A byId = aRepository.findById(idA).orElseThrow(NoSuchElementException);
aRepository.delete(byId);
}
}
存盤庫:
@Repository
public interface ARepository extends CrudRepository<A, Long>{
}
在呼叫 deleteB 時,外部服務已回傳此訊息:
Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-02292: integrity constraint violated (X.YY) - child record found
我該如何解決?似乎沒有考慮到 bRepository.delete(b);
PS我可以訪問外部服務,所以如果需要我可以修改它。
uj5u.com熱心網友回復:
您不能跨微服務進行這樣的事務 - 一個是因為您正在使用對服務 A 的遠程 http 呼叫,并且它本質上無法參與您在服務 B 中發起的事務。您正在使用的事務是資源本地事務。其次,您在服務中共享一個資料庫,而遠程 http 服務正試圖洗掉一條具有外鍵關系作為父項的記錄。由于您使用的是 Spring 事務管理器,因此您可以在 B 中的事務成功完成后使用TransactionEventListener(參見此處的示例用法)呼叫洗掉 A。還有其他模式可以解決跨微服務的事務,例如 Saga
uj5u.com熱心網友回復:
錯誤訊息表明洗掉尚未完成。我會嘗試的第一件事是洗掉后手動 bRepository.flush()。
您可以在此處閱讀有關重繪 的資訊:https : //www.baeldung.com/spring-data-jpa-save-saveandflush
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/363265.html
