perf(system): isSuperAdmin 切到 getUserRoleIdListByUserIdFromCache

修复 /admin-api/system/auth/get-permission-info 等接口大面积超时:

原因:ProjectSecurityWebFilter 每次 admin-api 请求都调一次
ProjectService.getAuthorizedProjectIds(userId),我之前在里面塞的
isSuperAdmin 用了无缓存的 getUserRoleIdListByUserId,
每请求一次 SELECT system_user_role,并发下直接打爆 DB。

切到 getUserRoleIdListByUserIdFromCache(@Cacheable 走 Redis
USER_ROLE_ID_LIST),首次查 DB、后续命中缓存,该缓存在
assignUserRole / processUserDeleted / updateUserRole 等写入点
都已正确 CacheEvict。

同时修正 UserProjectServiceImpl.isSuperAdmin 同样问题。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
lzh
2026-04-23 16:10:41 +08:00
parent 5dbc6c5e79
commit 317f1cd02f
2 changed files with 9 additions and 3 deletions

View File

@@ -170,13 +170,16 @@ public class ProjectServiceImpl implements ProjectService {
/**
* 判断用户是否为超级管理员
* 查角色列表 → hasAnySuperAdmin 判别
*
* 注意:必须使用 FromCache 版本,本方法被 ProjectSecurityWebFilter 每次请求都会调用,
* 走无缓存的 getUserRoleIdListByUserId 会直接把 system_user_role 打爆,
* 典型症状是 /admin-api/** 接口(如 get-permission-info大面积超时。
*/
private boolean isSuperAdmin(Long userId) {
if (userId == null) {
return false;
}
Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(userId);
Set<Long> roleIds = permissionService.getUserRoleIdListByUserIdFromCache(userId);
if (CollUtil.isEmpty(roleIds)) {
return false;
}

View File

@@ -258,12 +258,15 @@ public class UserProjectServiceImpl implements UserProjectService {
/**
* 判断用户是否超管
*
* 必须走 FromCache 版本否则调用点removeProjectUser / getProjectUserPage
* 在高并发场景(比如批量移除成员)下会放大 DB 压力。
*/
private boolean isSuperAdmin(Long userId) {
if (userId == null) {
return false;
}
Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(userId);
Set<Long> roleIds = permissionService.getUserRoleIdListByUserIdFromCache(userId);
if (CollUtil.isEmpty(roleIds)) {
return false;
}