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