{"record":{"id":"a2d7fdd50e4aa340","repo":"paascloud/paascloud-master","slug":"uac10011033","errorCode":"UAC10011033","errorMessage":"清空该用户常用菜单失败","messagePattern":"清空该用户常用菜单失败","errorType":"error_code","errorClass":"UacBizException","httpStatus":null,"severity":"error","filePath":"paascloud-provider/paascloud-provider-uac/src/main/java/com/paascloud/provider/service/impl/UacUserServiceImpl.java","lineNumber":897,"sourceCode":"\t\tif (count < 1) {\n\t\t\tthrow new UacBizException(ErrorCodeEnum.UAC10011032, loginName, email);\n\t\t}\n\t}\n\n\t/**\n\t * 删除用户菜单表\n\t */\n\tprivate int deleteUserMenuList(UacUserMenu uacUserMenu) {\n\t\tint selCount = uacUserMenuMapper.selectCount(uacUserMenu);\n\t\t// 如果查询结果为空, 默认认为已删除成功\n\t\tif (selCount < 1) {\n\t\t\treturn 1;\n\t\t}\n\n\t\tint delCount = uacUserMenuMapper.delete(uacUserMenu);\n\t\tif (delCount < selCount) {\n\t\t\tlogger.error(\"清空该用户常用菜单失败 delCount = {} selCount = {}\", delCount, selCount);\n\t\t\tthrow new UacBizException(ErrorCodeEnum.UAC10011033);\n\t\t}\n\n\t\treturn delCount;\n\t}\n\n\t/**\n\t * 校验数据是否合法\n\t *\n\t * @param menuIdList      需要操作的菜单Id集合\n\t * @param authResDto      登录用户\n\t * @param uacUserMenuList 需要插入的记录\n\t */\n\tprivate void checkUserMenuList(List<Long> menuIdList, LoginAuthDto authResDto, List<UacUserMenu> uacUserMenuList) {\n\n\t\tList<MenuVo> currentUserMenuVoList = uacMenuService.findAllMenuListByAuthResDto(authResDto);\n\t\tList<Long> currentUserMenuIdList = Lists.newArrayList();\n\t\tfor (MenuVo menuVo : currentUserMenuVoList) {\n\t\t\tLong menuId = menuVo.getId();","sourceCodeStart":879,"sourceCodeEnd":915,"githubUrl":"https://github.com/paascloud/paascloud-master/blob/781281a9503332ed3cef44ea618349d14230a127/paascloud-provider/paascloud-provider-uac/src/main/java/com/paascloud/provider/service/impl/UacUserServiceImpl.java#L879-L915","documentation":"UAC10011033 is thrown by the user-menu clearing logic when uacUserMenuMapper.delete(uacUserMenu) deletes fewer rows (delCount) than were previously selected (selCount). Since delete() removes all rows matching the criteria in one statement, delCount < selCount signals an internal inconsistency (rows vanished/changed between select and delete), so the method aborts with '清空该用户常用菜单失败'.","triggerScenarios":"Concurrent modification of the user's menu rows between the select counting them and the delete; the delete's WHERE criteria not matching all selected rows (e.g. partial key in the uacUserMenu template); DB errors silently reducing affected rows.","commonSituations":"Two tabs/requests re-saving the user's common menus at the same time; batch jobs deleting menus while a user saves preferences; logic bugs where the delete condition uses only userId while the select filtered by userId+something else.","solutions":["Investigate the select vs delete criteria mismatch — ensure the delete template matches exactly the rows counted by selCount.","Retry the whole select+delete operation under a transaction to eliminate the race window.","If partial deletes are acceptable in your flow, replace the strict delCount < selCount check with a logged warning.","Catch UacBizException(UAC10011033) and inform the user their menu save failed so they can retry."],"exampleFix":"// before\nint delCount = uacUserMenuMapper.delete(uacUserMenu);\nif (delCount < selCount) { throw new UacBizException(ErrorCodeEnum.UAC10011033); }\n// after\n@Transactional\npublic int clearUserMenu(Long userId) {\n    int selCount = countByUserId(userId);\n    int delCount = uacUserMenuMapper.deleteByUserId(userId);\n    if (delCount != selCount) { throw new UacBizException(ErrorCodeEnum.UAC10011033); }\n    return delCount;\n}","handlingStrategy":"retry","validationCode":"int selCount = uacUserMenuMapper.selectCount(template);\nif (selCount == 0) { return 0; } // nothing to clear, skip delete","typeGuard":null,"tryCatchPattern":"try {\n    int n = uacUserService.modifyUserMenus(...);\n} catch (UacBizException e) {\n    if (\"UAC10011033\".equals(e.getCode())) { return Result.fail(409, \"menu update conflict, please retry\"); }\n    throw e;\n}","preventionTips":["Wrap select+count and delete in one transaction to avoid the race window.","Make the delete criteria match the select criteria exactly.","Serialize menu saves per user (lock or optimistic versioning).","Treat transient mismatches as retryable conflicts rather than fatal errors."],"tags":["database","menu","consistency"],"backgroundTag":"database-write-failed","analyzedSha":"781281a9503332ed3cef44ea618349d14230a127","analyzedAt":"2026-09-10T10:59:02.070Z","contentChangedAt":"2026-09-10T10:59:02.070Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}