Postgres触发器更新Java缓存

Postgres触发器更新Java缓存,java,postgresql,stored-procedures,curl,triggers,Java,Postgresql,Stored Procedures,Curl,Triggers,我有一个Java web应用程序(部署到Tomcat的WAR),它在内存中保留一个缓存(Map)。我有一个Postgres数据库,其中包含一个widgets表: widget_id | widget_name | widget_value (INT) (VARCHAR 50) (INT) 为了在WidgetPOJO和widgets表记录之间进行O/R映射,我使用了MyBatis。我想实现一个解决方案,在widgets表中的值发生变化时,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缓存(映射)将实时更新。我可以有一个轮询组件,每隔(比如)30秒检查一次表,但在这里轮询并不是正确的解决方案。下面是我的建议:

  • 编写一个调用存储过程的Postgres触发器(
    run\u cache\u updater()
  • 该过程依次运行一个shell脚本(
    run\u cache\u updater.sh
  • 脚本base-64对更改的
    widgets
    记录进行编码,然后将编码的记录卷曲为HTTP URL
  • Java WAR有一个servlet监听卷曲的URL,并处理发送给它的任何
    HttpServletRequests
    。它对记录进行base-64解码,并以某种方式将其转换为
    小部件
    POJO
  • 缓存(
    Map
    )将使用正确的键/值进行更新
  • 这种解决方案感觉很尴尬,因此我首先想知道,任何Java/Postgres大师都会如何处理这种情况。在这里,投票是更好/更简单的选择吗(我只是很固执吗?)我是否忽略了另一个/更好/更标准的解决方案


    如果没有,并且这个解决方案是将更改的记录从Postgres推送到应用程序层的标准方法,那么我就要讨论如何编写触发器、存储过程和shell脚本,以便将整个
    小部件
    记录传递到cURL语句中。在此提前感谢您的帮助。

    我无法与MyBatis通话,但我可以告诉您,PostgreSQL有一个发布/订阅系统,这将使您能够以更少的黑客攻击完成这项工作

    首先,在
    widgets
    上设置触发器,该触发器在每次插入、更新和删除操作中运行。让它提取主键和
    widgets\u更改id
    。(从PL/pgSQL中,您可能希望
    执行pg_notify(…)
    )PostgreSQL将在事务提交时广播您的通知,使通知和相应的数据更改对其他连接可见

    在客户机中,您可能希望运行一个专用于保持此地图最新的线程。它将连接到PostgreSQL,
    widgets\u changed
    开始排队通知,
    SELECT*FROM widgets
    填充地图,并等待通知到达。(显然,检查通知很糟糕,但没有你想象的那么糟糕。有关具体实现,请参阅。)一旦看到通知,请查找指示的记录并更新地图。请注意,在首字母
    选择*
    之前必须
    收听
    ,因为可以在
    选择*
    收听
    之间更改记录


    这种方法不需要PostgreSQL了解有关应用程序的任何信息。它所要做的就是发送通知;您的应用程序完成其余的工作。没有shell脚本,没有HTTP,也没有回调,允许您重新配置/重新部署应用程序,而无需重新配置数据库。它只是一个数据库,可以对其进行备份、恢复、复制等操作,而不会带来额外的麻烦。类似地,您的应用程序也没有额外的复杂性:它所需要的只是一个到PostgreSQL的连接,而您已经有了这个连接。

    Wow-真棒的答案@willglynn(+1)-只是好奇:我想我可以通过JDBC运行一个
    LISTEN
    ?另外,
    PgNotificationPoller
    正是Postgres在幕后运行的东西,还是我需要添加到我的项目中才能使这个NOTIFY/LISTEN模型起作用?再次感谢
    LISTEN
    是一个命令,可使PostgreSQL将通知异步推送到您的连接,并在常规协议操作的同时以与
    NOTIFY
    相关的特殊消息传递。但是,JDBC驱动程序处理这些通知的方式存在一些特殊性(由于SSL限制),因此(
    “”
    )可以让驱动程序看到通知是可用的。这比
    libpq
    更糟糕,但仍然优于轮询表。为了更直接地回答您的问题,
    PgNotificationPoller
    和它的朋友是我发现的两件演示JDBC
    getNotifications()
    功能的东西。您可以使用这些工具,也可以按照中所述自行完成。