Spring 数据恢复 - 当@HandleBeforeSave 中发生 运行 次异常时事务未回滚?
Spring Data Rest - Transaction not rolled back when run-time exception occurs in @HandleBeforeSave?
我正在使用 Spring Data REST with Spring Boot 1.5.16,我的项目有以下实体。
Atoll.class
@Data
@Entity
public class Atoll {
@Id
@GeneratedValue
private long id;
private String atollName;
}
ErrorLog.class
@Data
@Entity
public class ErrorLog {
@Id
@GeneratedValue
private long id;
private String errorMessage;
public ErrorLog() {
}
public ErrorLog(String errorMessage) {
this.errorMessage = errorMessage;
}
}
我还有以下用于 Atoll class 的 RepositoryEventHandler。出于问题的目的,我只是在这里抛出一个例外。
@Component
@RepositoryEventHandler
public class AtollHandler {
@HandleBeforeSave
public void handleBeforeSave(Atoll atoll){
if(true){
throw new ResourceNotFoundException("A");
}
}
}
当我向 atolls/1
发送 PATCH 请求时,会记录运行时异常,但 Atoll 实体仍会更新。那我做错了什么?
我发现了一些类似的问题,例如 this one,但没有正确解释为什么会出现这种情况
注意:我还有一个 Rest 异常处理程序 class,它将错误日志写入数据库。当我注释掉代码的错误日志写入部分时,当发生运行时异常时,环礁实体不会得到更新
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
@Autowired
ErrorLogRepository errorLogRepository;
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<?> handleResourceNotFoundException(ResourceNotFoundException rnfe, HttpServletRequest request) {
ErrorLog errorLog = new ErrorLog(rnfe.getMessage());
errorLogRepository.save(new ErrorLog(rnfe.getMessage()));
return new ResponseEntity<>(errorLog, null, HttpStatus.NOT_FOUND);
}
}
我终于明白了。默认情况下 spring @Transactional 只捕获未经检查的异常。由于 ResourceNotFoundException 是由处理程序抛出的,它是一个已检查的异常,因此事务不会回滚。所以
@Transactional(rollbackFor = Exception.class)
注释需要添加到 AtollHandler class。
我正在使用 Spring Data REST with Spring Boot 1.5.16,我的项目有以下实体。
Atoll.class
@Data
@Entity
public class Atoll {
@Id
@GeneratedValue
private long id;
private String atollName;
}
ErrorLog.class
@Data
@Entity
public class ErrorLog {
@Id
@GeneratedValue
private long id;
private String errorMessage;
public ErrorLog() {
}
public ErrorLog(String errorMessage) {
this.errorMessage = errorMessage;
}
}
我还有以下用于 Atoll class 的 RepositoryEventHandler。出于问题的目的,我只是在这里抛出一个例外。
@Component
@RepositoryEventHandler
public class AtollHandler {
@HandleBeforeSave
public void handleBeforeSave(Atoll atoll){
if(true){
throw new ResourceNotFoundException("A");
}
}
}
当我向 atolls/1
发送 PATCH 请求时,会记录运行时异常,但 Atoll 实体仍会更新。那我做错了什么?
我发现了一些类似的问题,例如 this one,但没有正确解释为什么会出现这种情况
注意:我还有一个 Rest 异常处理程序 class,它将错误日志写入数据库。当我注释掉代码的错误日志写入部分时,当发生运行时异常时,环礁实体不会得到更新
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
@Autowired
ErrorLogRepository errorLogRepository;
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<?> handleResourceNotFoundException(ResourceNotFoundException rnfe, HttpServletRequest request) {
ErrorLog errorLog = new ErrorLog(rnfe.getMessage());
errorLogRepository.save(new ErrorLog(rnfe.getMessage()));
return new ResponseEntity<>(errorLog, null, HttpStatus.NOT_FOUND);
}
}
我终于明白了。默认情况下 spring @Transactional 只捕获未经检查的异常。由于 ResourceNotFoundException 是由处理程序抛出的,它是一个已检查的异常,因此事务不会回滚。所以
@Transactional(rollbackFor = Exception.class)
注释需要添加到 AtollHandler class。