我正在使用Spring Boot v2.1.3.RELEASE和Hibernate v5.3.6构建应用程序。
我要完成的工作是在服务上使用@Transactional批注,以确保在删除记录时,如果发生错误(数据库或业务逻辑异常),则将从事务中删除的所有记录都回滚到原始记录删除之前的状态。
我要开始交易的服务是MasterSpecService
,然后像这样调用其他服务:
deleteMasterSpec(MasterSpec masterSpec) {
this.approvalTargetService.deleteApprovalTargetsForSpec(masterSpec.getSysI());
this.approvalToleranceService.deleteApprovalTolerancesForSpec(masterSpec.getSysI());
this.receivingToleranceService.deleteReceivingTolerancesForSpec(masterSpec.getSysI());
this.finishedGoodTargetService.deleteFinishedGoodTargetsForSpec(masterSpec.getSysI());
this.finishedGoodToleranceService.deleteFinishedGoodTolerancesForSpec(masterSpec.getSysI());
this.maxValueService.deleteMaxValuesForSpec(masterSpec.getSysI());
this.ingredientService.deleteSpecIngredients(masterSpec.getSysI());
this.masterSpecRepo.deleteById(masterSpec.getSysI());
// throw some exception here as a test, and have all the deletes rollback
}
在数据库中,目标,公差,最大值和成分的表都具有对MasterSpec表的外键引用,因此我最后删除了MasterSpec。
我希望MasterSpecService
是主要交易,并让所有其他服务附加到该交易中,因此,如果发生任何故障,它将还原。所有服务都有自己的JPA信息库来处理删除操作。
是否可以通过@Transactional注释来完成?
或者,当我在MasterSpec记录上调用delete时,如果事务的任何部分失败了,将在我的各个Entity类中使用@OneToMany和@ManyToOne映射完成相同的任务并还原所有已删除的记录吗?
答案 0 :(得分:0)
经过进一步的挖掘,就像我在问题末尾提到的那样,一种更合适的方法是在类上使用带有@ OneToOne,@ OneToMany和@ManyToOne批注的双向映射。
在我的Entity类PMasterSpec.java中,添加了:
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "masterSpec")
private PApprovalTarget approvalTarget;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "masterSpec")
private PApprovalTolerance approvalTolerance;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "masterSpec")
private PReceivingTolerance receivingTolerance;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "masterSpec")
private PFinishedGoodTarget finishedGoodTarget;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "masterSpec")
private PFinishedGoodTolerance finishedGoodTolerance;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "masterSpec")
private PMaxValue maxValue;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "masterSpec")
private List<PIngredient> ingredients;
在PApprovalTarget,PApprovalTolerance,PReceivingTolerance,PFinishedGoodTarget,PFinishedGoodTolerance,PMaxValue实体类中,我通过外键映射回了PMasterSpec类:
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "BOM_SPEC_SYS_I")
private PMasterSpec masterSpec;
在PIngredient类中:
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "BOM_SPEC_SYS_I", insertable = false, updatable = false)
private PMasterSpec masterSpec;
我的MasterSpecService仍被标记为事务性的:
@Transactional(propagation = Propagation.REQUIRED)
但是其他所有服务都不是。
现在,只要我构建PMasterSpec对象并提供所有其他嵌套的实体类,当我调用masterspecRepo.save(masterSpec)
时,它将创建单个事务来保存所有实体对象,并在保存或删除时回滚所有内容发生问题。
我遵循以下示例: