【发布时间】:2019-06-20 01:32:50
【问题描述】:
我有一个文件存储应用程序,它有两个服务(作业服务和文件服务)作为 Spring Boot 应用程序。当用户上传文件时,根据文件类型,它通过弹簧批处理作业进行处理,其缩略图和预览是使用 FFMpeg 和/或 ImageMagick 生成的。然后将这些数据写入数据库(目前在本地 Microsoft SQL Server 2017 Developer 上开发)。
较小的文件按预期工作,但我想通过发送一堆较大的音频和视频文件来测试应用程序并开始刷新文件页面以查看文件是否已处理。然而,经过几次刷新后,UI 一直处于“正在加载”状态,直到 spring 批处理作业结束,然后按预期显示结果。
我运行了相同的测试并检查了网络选项卡,并注意到为检索文件列表而进行的调用处于“待处理”状态。它一直停留在该阶段,直到批处理的其余部分完成并返回成功 (200)。
在web服务端调试后发现文件服务应用卡在下面一行:
List<Asset> allAssets = jdbcTemplate.query("SELECT asset_id, asset_extension, asset_import_date, asset_imported_by_username, asset_name, asset_path, asset_preview_path, asset_thumbnail_path, asset_type FROM assets", new AssetRowMapper());
所以在我的场景中,当我刷新文件页面时,我试图访问资产表,因为春季批处理作业也在同一个表上工作以插入和更新每个文件相关数据。我想也许插入和更新查询以某种方式优先,并从我的选择查询中锁定表。所以我从 assets 表中创建了一个视图并将我的查询更改为:
List<Asset> allAssets = jdbcTemplate.query("SELECT asset_id, asset_extension, asset_import_date, asset_imported_by_username, asset_name, asset_path, asset_preview_path, asset_thumbnail_path, asset_type FROM assets_vw", new AssetRowMapper());
不幸的是,这不起作用,我得到了相同的结果。
要查看此问题是源自应用程序端(我的代码)还是数据库端,我运行了相同的测试,但我通过数据库上的 SQL Management Studio 手动运行了相同的查询。有趣的是,在几次成功的查询之后(正如我在 UI 上看到的那样),我得到了相同的结果,查询一直停留在“执行”阶段,直到其余的 spring 批处理作业完成。
看来问题出在数据库方面。
我检查了我的数据库上的最大连接数(如各种帖子中所建议的那样),它已经是默认值 0(无限制)。
此时我不确定我的数据库(或我的代码)出了什么问题。任何帮助将不胜感激。
【问题讨论】:
-
发生这种情况时运行 sp_WhoIsActive。你可以谷歌一下,找到它的文档。可能发生的情况是您遇到阻塞。为了使 SQL Server 成为 ACID,必须在某些对象(行、表、方案)上工作时对其进行锁定。您可以查看这些锁、它们的优先级、共享锁、阻塞和死锁,以更好地理解它。我在这里解释得太深入了,许多专家都有数小时的视频或博客页面。
标签: sql-server spring-boot spring-batch spring-jdbc