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
相关产品推荐
相关产品推荐

