Search code examples
javagrailsgroovygrails-orm

Make delete from Database and delete from FileSystem transactional?


I have the following method which deletes an image from the file system and its corresponding records from the database.

  boolean delete(ImageItem imageItem) {
    boolean success = false
    String imageId = imageItem.id

    ...

    Path outFile = Paths.get(fileUrl)
    if (Files.deleteIfExists(outFile)) {
      log.debug "delete() - file deleted: ${fileUrl}"
      success = true
    }

    try{
      imageItem.delete(flush: true)
    } catch (Exception e) {
      log.debug "delete() - Record deleted failed: ${e}"
      success = false
    }

    return success
  }

I want to make both delete operations transactional meaning that either both operations proceed or non.

Is there a way of doing this?


Solution

  • Sure you can do it!

    ImageItem.withTransaction {status ->
       try {
          imageItem.delete(flush: true)
       } catch (Exception e) {
          status.setRollbackOnly()   
          return 
       }
    
       Path outFile = Paths.get(fileUrl)
       try{
          if (Files.deleteIfExists(outFile)) {
            log.debug "delete() - file deleted: ${fileUrl}"
          } catch (e) {
             status.setRollbackOnly()
          }
    }
    

    First you try to delete the database record (rolling back if it fails) and then you delete the actual file(s).

    https://grails.github.io/grails-doc/latest/ref/Domain%20Classes/withTransaction.html