Postgres触发器更新Java缓存
我有一个Java web应用程序(部署到Tomcat的WAR),它在内存中保留一个缓存(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缓存(映射)将实时更新。我可以有一个
Map
)。我有一个Postgres数据库,其中包含一个widgets
表:
widget_id | widget_name | widget_value
(INT) (VARCHAR 50) (INT)
为了在Widget
POJO和widgets
表记录之间进行O/R映射,我使用了MyBatis。我想实现一个解决方案,在widgets
表中的值发生变化时,Java缓存(映射)将实时更新。我可以有一个轮询组件,每隔(比如)30秒检查一次表,但在这里轮询并不是正确的解决方案。下面是我的建议:
run\u cache\u updater()
)run\u cache\u updater.sh
)widgets
记录进行编码,然后将编码的记录卷曲为HTTP URLHttpServletRequests
。它对记录进行base-64解码,并以某种方式将其转换为小部件
POJOMap
)将使用正确的键/值进行更新如果没有,并且这个解决方案是将更改的记录从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
和它的朋友是我发现的两件演示JDBCgetNotifications()
功能的东西。您可以使用这些工具,也可以按照中所述自行完成。