在使用@Transational完成某些功能后,我尝试进行回滚
当由于sql而导致错误并提交时,回滚有效。
控制器
@RestController
@RequestMapping()
@Slf4j
@AllArgsConstructor
public class Controller {
private final MyServiceImpl myService;
@PostMapping("/truc")
public void truc() {
Entity ent = new Entity();
myService.createEntity(ent);
Entity2 ent2 = new Entity2();
myService.createEntity2(ent2);
boolean b = {some conditions};
if(b){
//to do flush
}
else{
//to do rollback to get initial state before createEntity()
}
}
}
MyServiceImpl
@Transactional
@Slf4j
@AllArgsConstructor
public class SiteServiceImpl {
//Repositories associed with entities extends JpaRepository
private RepoEntity repoEntity;
private RepoEntity2 repoEntity2;
@Transactional
protected void createEntity(Entity ent){
this.repoEntity.save(ent);
}
@Transactional
protected void createEntity2(Entity2 ent){
this.repoEntity2.save(ent);
}
}
我将能够以编程方式回滚和取消两个保存的实体。我不是Spring的专家,也不知道该怎么做。可能与配置有关?
感谢您的帮助。
答案 0 :(得分:2)
在@Transactional
级使用Controller
。要触发回滚,请从控制器中抛出RuntimeException
。
如下所示:
public class Controller {
private final MyServiceImpl myService;
@Transactional
@PostMapping("/truc")
public void truc() {
Entity ent = new Entity();
myService.createEntity(ent);
Entity2 ent2 = new Entity2();
myService.createEntity2(ent2);
boolean b = {some conditions};
if(b){
//to do flush
}
else{
//This will trigger rollback
throw new RuntimeException("I want to rollback to cancel what I did in this method");
}
}
}
答案 1 :(得分:1)
您可以将新方法添加到MyServiceImpl
中,以调用内部的两个createEntity()
方法。之后,此方法中的所有业务逻辑将被事务处理,并在抛出RuntimeException时自动回滚(对于检查的异常,请使用rollBackFor),因为您的服务类已标记为事务性。
如果您在类中添加MyServiceImpl
批注,则@Transactional
中的所有公共方法也将变为事务性的。不需要在方法上单独注释(除非您要更改某些事务参数,如隔离,传播等),