我有一个存储在磁盘上的文件,可以访问Web场中的多个服务器。根据数据库中的数据更改,根据需要更新此文件。我有一个数据库表,它存储一个带有此文件的URI的行,以及一些基于某些数据库表的散列。如果散列与其各自的表不匹配,则需要重新生成文件并需要插入新行。
如何使它只有1个客户端重新生成此文件并插入一行?
最容易但最糟糕的解决方案(因为锁定)是:
BEGIN TRANSACTION
SELECT ROW FROM TABLE (lock the table for the remainder of the transaction)
IF ROW IS OUT OF DATE:
REGENERATE FILE
INSERT ROW INTO TABLE
DO SOME STUFF WITH FILE (30s)
COMMIT TRANSACTION
但是,如果多个客户端执行此代码,则所有后续客户端都会长时间处于“使用文件进行处理”过程中。
有没有更好的方法来解决这个问题?也许在提交之前改变我处理文件的方式以使其更快?我已经被困了几天了。
答案 0 :(得分:2)
听起来您需要异步进行文件处理,因此文件进程将被分离并且事务会及时完成。有几种方法可以做到这一点,但最简单的方法可能是用“将一条记录插入表格This_File_Needs_To_Be_Updated”替换“使用文件填充”,然后每隔几分钟运行一次更新该表中每条记录的作业。或者HERE是一些可以动态生成作业的代码。或者请参阅Stack Overflow上的THIS问题。
答案 1 :(得分:1)
答案取决于文件级处理的细节。
如果您只是交换数据库和文件操作,则可能会损坏文件或忙于等待(具体取决于您打开它的确切程度以及拒绝并发打开时代码的作用)。繁忙的等待肯定比从吞吐量(或任何其他)角度等待数据库锁更糟糕。
如果您的文件处理确实需要经常导致请求排队,那么唯一的解决方案是添加更强大的硬件或优化文件级处理。
例如,如果文件仅反映数据库中的数据,则可能完全没有更新它,并且具有基于数据库中的数据定期重新生成其内容的后台进程。您可能需要添加版本控制,以确保读取文件的任何人都没有收到过时数据。如果URL指向的文件每次都有一个新名称,您可能需要一个错误处理程序,以确保GET
个请求不习惯性地接收新文件的404
响应。