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秒检查一次表,但轮询只是不适合这里的解决方案。 所以这就是我的建议:

  1. 编写一个调用存储过程的Postgres触发器( run_cache_updater()
  2. 该过程run_cache_updater.sh运行shell脚本( run_cache_updater.sh
  3. 脚本base-64对已更改的widgets记录进行编码,然后将编码记录cURL到HTTP URL
  4. Java WAR有一个servlet侦听cURLed URL并处理发送给它的任何HttpServletRequests 。 它base-64解码记录并以某种方式将其转换为Widget POJO。
  5. 缓存( 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的连接。