You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Liferay 6.2清理USERNOTIFICATIONEVENT后通知Portlet异常求助

Liferay 6.2通知计数与数据库记录不符问题分析与解决

你的问题核心是Liferay的通知计数缓存机制与手动清理数据库记录不同步导致的,具体原因和解决方法如下:

为什么会出现计数与实际记录不符?

  • 会话级缓存残留:用户登录后,Liferay会将未读通知计数加载到用户的Session中,不会每次打开通知Portlet都去数据库实时查询。你手动清空数据库表后,Session里的旧计数(20条)并没有被更新,所以登录后仍显示旧数值。
  • 实体缓存未刷新:Liferay使用Ehcache缓存实体对象,UserNotificationEvent的缓存可能还保留着已删除记录的引用。当你点击通知时,Portlet尝试从缓存中获取ID为115765的记录,但数据库里已经不存在,就抛出了NoSuchUserNotificationEventException。
  • 计数累加逻辑:新增通知时,系统会直接在当前会话的计数基础上+1(20+1=21),而不是重新从数据库统计实际记录数,导致计数进一步偏离实际。

解决方法

1. 强制刷新用户会话

让受影响的用户完全退出并重新登录,这样Session里的旧计数会被清除,重新从数据库读取(此时数据库为空,计数会显示0)。

2. 清除Liferay缓存

通过控制面板操作:

  • 登录Liferay管理员账号,进入控制面板 -> 服务器管理 -> 缓存页面。
  • 在缓存列表中找到com.liferay.portlet.notifications.model.UserNotificationEvent相关的缓存项,点击“清除”;或者直接点击“清除所有缓存”来刷新全部缓存。

如果无法通过控制面板操作,重启Liferay服务器也能彻底清空所有缓存。

3. 后续避免手动删库,使用官方API删除通知

手动删除数据库记录会跳过Liferay的缓存更新逻辑,正确的做法是使用Liferay的LocalService API来清理旧通知:

// 清理指定用户30天前的所有旧通知
UserNotificationEventLocalServiceUtil.deleteUserNotificationEvents(userId, System.currentTimeMillis() - 30*24*60*60*1000);

// 或者清空所有用户的旧通知
List<UserNotificationEvent> oldEvents = UserNotificationEventLocalServiceUtil.getUserNotificationEvents(0, UserNotificationEventLocalServiceUtil.getUserNotificationEventsCount());
for(UserNotificationEvent event : oldEvents) {
    UserNotificationEventLocalServiceUtil.deleteUserNotificationEvent(event);
}

这样操作会同时更新数据库和缓存,避免出现计数不一致的问题。

内容的提问来源于stack exchange,提问作者ktsigkounis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:33:25