Spring如何处理文件保存

时间:2015-06-28 15:21:56

标签: java spring transactions

在应用程序中我正在将文件保存到文件系统,然后更新数据库。我的问题是:我应该在交易中还是在交易之前完成?

目前我这样做 - 在交易之前,如果保存文件出现故障,它不会更新数据库:

@POST
@Path("passport")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response saveDocument(@FormDataParam("file") InputStream uploadedInputStream,
                                   @FormDataParam("file") FormDataContentDisposition fileDetail,
                                   @FormDataParam("documentTypeId") int documentTypeId,
                                   @FormDataParam("id") int id) {

    String fileName = fileDetail.getFileName();
    String result = "";
    String[] split = fileName.split("\\.");
    if (split.length == 1) {
        //No extension
        result = split[0] + new Date().getTime();
    } else {
        for (int i = 0; i < split.length - 1; i++) {
            result += split[i];
        }
        result += new Date().getTime() + "." + split[split.length - 1];
    }
    try {
        fileService.saveFile(result, uploadedInputStream);
        persistenceService.saveDocument(fileName, id, documentTypeId);
    } catch (IOException e) {
        LOGGER.log(Level.SEVERE, "File saving failed", e);
       //TODO Throw exception
    }

    return Response.ok().build();
}

如果我以这种方式保存,我无法确保如果在事务期间发生异常,则不保存文件。逻辑方法是在事务中更新数据库后进行保存,以便在发生异常时回滚事务。但我不确定在事务中执行I / O操作是否是一种好习惯。

2 个答案:

答案 0 :(得分:0)

这不是直截了当的!原因是,很难在一个&#34;库中完成一个完整的回滚系统。通用级别足以在所有文件系统中工作。您可能认为这很容易,但事实并非如此,并且需要OS和文件系统支持。

以下面的例子为例,如果你要写一个新文件,回滚只是删除文件。如果要删除文件,则回滚会取消删除(需要操作系统支持)。最后,如果要修改文件,则需要返回到事务之前的状态(需要访问某些文件系统上的日志)。

现在绝对是原子的,Java库需要直接使用新闻系统,这样即使JVM在事务中崩溃,JFS也会回滚文件更改。

考虑使用文件系统层,甚至某种类型的NoSQL数据库,而不是保存到文件中?

答案 1 :(得分:0)

您可以使用XADisk

处理文件系统上的事务操作