在应用程序中我正在将文件保存到文件系统,然后更新数据库。我的问题是:我应该在交易中还是在交易之前完成?
目前我这样做 - 在交易之前,如果保存文件出现故障,它不会更新数据库:
@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操作是否是一种好习惯。
答案 0 :(得分:0)
这不是直截了当的!原因是,很难在一个&#34;库中完成一个完整的回滚系统。通用级别足以在所有文件系统中工作。您可能认为这很容易,但事实并非如此,并且需要OS和文件系统支持。
以下面的例子为例,如果你要写一个新文件,回滚只是删除文件。如果要删除文件,则回滚会取消删除(需要操作系统支持)。最后,如果要修改文件,则需要返回到事务之前的状态(需要访问某些文件系统上的日志)。
现在绝对是原子的,Java库需要直接使用新闻系统,这样即使JVM在事务中崩溃,JFS也会回滚文件更改。
考虑使用文件系统层,甚至某种类型的NoSQL数据库,而不是保存到文件中?
答案 1 :(得分:0)
您可以使用XADisk
处理文件系统上的事务操作