【发布时间】:2020-05-14 12:29:54
【问题描述】:
我正在构建一个 Web 应用程序,用户可以在其中创建报告,然后为创建的报告上传一些图像。当用户单击报告页面上的按钮时,这些图像将在浏览器中呈现。这些图像是机密的,只有授权用户才能访问它们。
我知道将图像存储在数据库、文件系统或亚马逊 S3 等服务中的优缺点。对于我的应用程序,我倾向于将图像保留在文件系统中,并将图像的路径保留在数据库中。这意味着我必须处理围绕分布式事务管理出现的问题。我需要一些关于如何处理这些问题的建议。
1- 我认为正确的解决方案之一是使用 JTA 和 XADisk 等技术。我对这些技术不是很了解,但我相信 2 阶段提交是如何实现自动性的。我使用 MySQL 作为数据库,似乎 MySQL 支持 2 阶段提交。这种方法的问题是 XADisk 似乎不是一个活跃的项目,并且没有太多关于它的文档,而且事实上我对这种方法的来龙去脉不是很了解。我不确定是否应该投资这种方法。
2- 我相信我可以解决一些因违反我的应用程序的 ACID 属性而引起的问题。上传图片时,我可以先将文件写入磁盘,如果此操作成功,我可以更新数据库中的路径。如果数据库事务失败,我可以从磁盘中删除文件。我知道这仍然不是防弹的;在数据库事务之后可能会发生电力短缺,或者磁盘可能暂时没有响应等......我知道还有并发问题,例如,如果一个用户试图修改上传的图像而另一个用户试图在同时,也会出现一些问题。我的应用程序中并发更新的机会仍然相对较低。
如果发生这种异常情况,我相信我可以忍受磁盘上的孤立文件或数据库上的孤立图像路径。如果文件路径存在于 db 而不是文件系统中,我可以在报告页面上向用户显示通知,他可能会尝试重新上传图像。文件系统中的孤立文件不会有太大问题,我可能会不时运行一个进程来检测这些文件。不过,我对这种方法不是很满意。
3- 最后一个选项可能是根本不在数据库中存储文件路径。我可以构建文件系统,以便可以在代码中推断文件路径并一次加载所有图像。例如,我可以为每个报告创建一个名为报告 ID 的文件夹。当请求加载报告的图像时,我可以立即加载图像,因为我知道报告 ID。这最终可能会导致文件系统中有大量文件夹,我不确定这样的设计是否可以接受。在这个方案中仍然存在并发问题。
对于我应该遵循哪种方法,我将不胜感激。
【问题讨论】:
-
任何解决方案都有利有弊。我会选择你可以先开始工作并从那里适应的解决方案。我也不会担心文件上的事务,只需存储到磁盘并偶尔清理一次。 Linux 可以告诉您上次访问文件的时间。
-
@lfmunoz 感谢您的建议。实际上,我现在最终将图像存储为 LOB,我可以非常快速地完成这项工作。如果我看到需要,我会更改实现。
标签: database transactions jta xadisk