问题描述
我试图实现的目标是对数据库进行更新".然后执行删除"操作带有Spring Data JPA和@Transactional批注的操作,我希望两个操作都执行,但是如果其中一个操作失败,则需要回滚,我该如何正确执行此操作?
Hi what i trying to achieve is to do "UPDATE" action and then do "DELETE" action with Spring Data JPA and @Transactional annotation, and i want both action is executed but if one of the action is failed, i need a rollback, how do i do this properly?
首先是我的服务班级:
@Transactional
@Service
public class TransDeliveryPlanningService {
public ResponseRequest<TransDeliveryPlanning> deleteTransDeliveryPlanning(InputDeleteRequest<ViewAndDeleteRequest> request) {
String currentUser = request.getLoggedInUser();
String reasonDeleted = request.getReason();
Long id = request.getObject().getId();
ResponseRequest<TransDeliveryPlanning> response = new ResponseRequest<TransDeliveryPlanning>();
TransDeliveryPlanning transDeliveryPlanningOld = transDeliveryPlanningRepository.findById(id).orElseThrow(() -> new ResourceNotFound("Data "+ id +" not found!"));
transDeliveryPlanningOld.setIsDeleted(true);
transDeliveryPlanningOld.setReasonDeleted(reasonDeleted);
transDeliveryPlanningOld.setModifiedBy(currentUser);
TransDeliveryPlanning updatedTransDeliveryPlanning = transDeliveryPlanningRepository.save(transDeliveryPlanningOld);
transDeliveryPlanningRepository.delete(transDeliveryPlanningOld);
//NOTE delete transStuffing
List<TransStuffing> transStuffing = transStuffingRepository.findBydeliveryPlanningId(transDeliveryPlanningOld.getId());
Boolean deletePermit = false;
for(TransStuffing ts : transStuffing) {
if(ts.getStatus().equalsIgnoreCase("new")) {
deletePermit = true;
} else {
throw new ResourceIsDelete("Stuffing " + ts.getStuffingNo() + " Status already changed, delete is not permited!");
}
}
if(deletePermit){
transStuffingRepository.deleteAll(transStuffing);
}
//NOTE end of delete transStuffing
if(updatedTransDeliveryPlanning != null) {
response.setResponse("Sukses Hapus");
response.setObject(updatedTransDeliveryPlanning);
} else {
response.setResponse("Gagal Hapus");
}
return response;
}
}
如您所见,我执行 transDeliveryPlanningRepository.save
,然后下一行执行 transDeliveryPlanningRepository.delete
,我需要执行的下一个仓库是 transStuffingRepository.deleteAll
as you can see, i do transDeliveryPlanningRepository.save
and then the next line i do transDeliveryPlanningRepository.delete
and the next repo i need to execute is transStuffingRepository.deleteAll
我需要在删除之前保存的目标是使用Hibernate Audit Envers创建AuditLog,因此我想将删除原因记录到我的审核表中,然后删除记录.但是,当我使用**@Transactional**
注释但未执行 transDeliveryPlanningRepository.save
(更新)时,我的函数只是执行 transDeliveryPlanningRepository.delete
和 transStuffingRepository.deleteAll
如何使用@Transactional批注保持保存?
The goal i need to do save before delete is i use Hibernate Audit Envers to create an AuditLog, so i want log the delete reason into my audit table and then delete the record. But when i use **@Transactional**
annotation the transDeliveryPlanningRepository.save
(update) not executed, my function just execute transDeliveryPlanningRepository.delete
and transStuffingRepository.deleteAll
how i keep the save executed with @Transactional annotation?
更新
正如Morteza Bandi回答以下建议一样,这是我的更新代码:这是我的资料库:
As Morteza Bandi answer below suggestion, here is my updated code :here is my repository :
@Repository
public interface TransDeliveryPlanningRepository extends RevisionRepository<TransDeliveryPlanning, Long, Integer>, JpaRepository<TransDeliveryPlanning, Long> {
@Modifying
TransDeliveryPlanning save(TransDeliveryPlanning transDeliveryPlanning);
}
当我这样做时,仍然不能在删除前进行更新,我在这里还想念什么?
when i do this, still it's not update before delete, what did i still miss here?
推荐答案
尝试将@Transactional
放在service
方法内部的方法上方.例如:
try putting @Transactional
above a method inside service
method. e.g.:
@Service
public class MyService {
@Autowired
private MyRepo myRepo;
@Autowired
private MyRepo2 myRepo2;
@Transactional
public void yourTransactionService(arguments){
*** your DML operations here ***
e.g.
myRepo.save(blabla);
myRepo.delete(blabla1);
...
myRepo2.save(blabla2);
myRepo3.delete(blabla3);
...
}
}
这样,在调用yourTransactionService(arguments)
时,所有DML
都将保留或不保留.
This way when calling yourTransactionService(arguments)
either all the DML
s are persisted or none of them persisted.
这篇关于如何在JPA中强制@Transactional提交两个存储库操作,而不仅仅是最后一个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!