我有一个Java Web应用程序(部署到Tomcat的WAR),它将缓存(Map<Long,Widget>
)保留在内存中。我有一个包含widgets
表的Postgres数据库:
widget_id | widget_name | widget_value
(INT) (VARCHAR 50) (INT)
要在Widget
POJO和widgets
表记录之间进行O / R映射,我使用的是MyBatis。我想实现一个解决方案,只要widgets
表中的值发生变化,Java缓存(Map)就会实时更新。我可能有一个轮询组件,每隔30秒检查一次表,但轮询只是不适合这里的解决方案。所以这就是我的建议:
run_cache_updater()
)run_cache_updater.sh
)widgets
记录进行编码,然后将编码记录cURL为HTTP URL HttpServletRequests
。它base-64解码记录并以某种方式将其转换为Widget
POJO。Map<Long,Widget>
)。这个解决方案感觉很尴尬,所以我首先想知道那里的Java / Postgres大师会如何处理这种情况。在这里轮询更好/更简单的选择(我只是顽固吗?)我还有其他/更好/更标准的解决方案吗?
如果没有,并且此解决方案是将已更改的记录从Postgres推送到应用程序层的标准方法,那么我就会扼杀如何编写触发器,存储过程和shell脚本以便整个{{1} } record被传递到cURL语句中。在此提前感谢您的任何帮助。
答案 0 :(得分:3)
我不能和MyBatis说话,但我可以告诉你PostgreSQL有一个发布/订阅系统,这样可以让你以更少的hackery做到这一点。
首先,在每个插入,更新和删除操作上运行的widgets
上设置一个触发器。让它提取主键和NOTIFY
widgets_changed, id
。 (好吧,从PL / pgSQL开始,你可能想要PERFORM pg_notify(...)
。)如果该事务提交,PostgreSQL将广播你的通知,使通知和相应的数据变化对其他连接可见。
在客户端中,您需要运行专用于使此映射保持最新的线程。它将连接到PostgreSQL,LISTEN
widgets_changed
以开始排队通知,SELECT * FROM widgets
来填充地图,并等待通知到达。 (显然检查通知involves polling the JDBC driver,这很糟糕,但没有您想象的那么糟糕。请参阅PgNotificationPoller了解具体实现。)一旦看到通知,请查看指示的记录并更新地图。请注意,在LISTEN
之前SELECT *
非常重要,因为记录可以在SELECT *
和LISTEN
之间更改。
此方法不要求PostgreSQL了解您的应用程序。它所要做的就是发送通知;你的申请完成剩下的工作。没有shell脚本,没有HTTP,也没有回调,让您无需重新配置数据库即可重新配置/重新部署应用程序。它只是一个数据库,它可以备份,恢复,复制等,没有额外的复杂性。同样,您的应用程序没有额外的复杂性:它所需要的只是与您已经拥有的PostgreSQL的连接。