0

I'm trying to implement rollback mechanism for saving image to AWS/S3 and also Its metadata to the AWS/RDS. But I got confused about handling exceptions. Spring documentation is not clear about throwing exceptions.

I want to delete S3 record if I Can't save metadata to the RDS.

Image img = s3Service.saveImageToS3(file, description);
img = rdsRepository.save(img);

// couldn't save to RDS, so rollback from S3
if(img.getId()==0){
    s3Service.deleteImageFromS3(img);
    return new ResponseEntity<>(img, HttpStatus.INTERNAL_SERVER_ERROR);
}else {
    return new ResponseEntity<>(img, HttpStatus.CREATED);
}

rdsRepository which I used above, extends "org.springframework.data.repository.CrudRepository"

public interface RdsRepository extends CrudRepository<Image, Long> {

Image class:

@Entity(name="Image")
@Data
@AllArgsConstructor @NoArgsConstructor
public class Image {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;

As far as I know, CrudRepository.save() method can throws only unchecked exceptions. Because of that I shouldn't catch them. Is this approach correct? If yes, What can be alternative solution?

eka
  • 1
  • 1

1 Answers1

0

Surround with just Exception or RuntimeException

Image img = s3Service.saveImageToS3(file, description);
    try {
        img = rdsRepository.save(img);
    } catch (Exception e) {
        //Rollback saveImageToS3
        throw e;
    }

    // couldn't save to RDS, so rollback from S3
    if(img.getId()==0){
        s3Service.deleteImageFromS3(img);
        return new ResponseEntity<>(img, HttpStatus.INTERNAL_SERVER_ERROR);
    }else {
        return new ResponseEntity<>(img, HttpStatus.CREATED);
    }

In fact is no mather wath Exception is thrown - result is this same - not saved data.

Victor1125
  • 642
  • 5
  • 16
  • Is this not bad practice? Handling with Exception base class? Check link please: https://stackoverflow.com/questions/2416316/why-is-the-catchexception-almost-always-a-bad-idea – eka Dec 07 '20 at 10:10
  • I don't see, is that the base class. Yyou have to catch exception, to process rollback, then you throw existed exception. I think in your case, is no mather what kind of exception is, becasuse in all situations with exception data is no storred, so you must rollback image. If you have specific exception, you can use them, but I will use Exception or RuntimeException in this case. – Victor1125 Dec 08 '20 at 08:21
  • Anyway, for me better solution is create custom rollback for `@Transactional`, because now you mix business process with implementation of save and rollback process. – Victor1125 Dec 08 '20 at 08:25
  • to complate my example, I add `throw e`, it's important but I forgot – Victor1125 Dec 08 '20 at 08:31