Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通知postgres对java应用程序的更改 问题_Java_Postgresql_Indexing_Synchronization_Replication - Fatal编程技术网

通知postgres对java应用程序的更改 问题

通知postgres对java应用程序的更改 问题,java,postgresql,indexing,synchronization,replication,Java,Postgresql,Indexing,Synchronization,Replication,我正在为几十万种产品建立一个postgres数据库。我将设置一个索引(Solr或ElasticSearch)以缩短复杂搜索查询的查询时间 现在的重点是如何让索引与数据库同步? 在过去,我有一种应用程序,它定期轮询数据库以检查应该进行的更新,但是我会有一个过时的索引状态时间(从数据库更新到索引更新) 我更喜欢这样一种解决方案:数据库将通知我的应用程序(java应用程序)数据库中的某些内容已更改,此时应用程序将决定是否需要更新索引。更准确地说,我将构建一种生产者和消费者结构,希望复制副本将收到来自p

我正在为几十万种产品建立一个postgres数据库。我将设置一个索引(Solr或ElasticSearch)以缩短复杂搜索查询的查询时间

现在的重点是如何让索引与数据库同步?

在过去,我有一种应用程序,它定期轮询数据库以检查应该进行的更新,但是我会有一个过时的索引状态时间(从数据库更新到索引更新)

我更喜欢这样一种解决方案:数据库将通知我的应用程序(java应用程序)数据库中的某些内容已更改,此时应用程序将决定是否需要更新索引。更准确地说,我将构建一种生产者和消费者结构,希望复制副本将收到来自postgres的通知,指出发生了变化,如果这与索引数据相关,那么它将存储在一个更新堆栈中。使用者将使用此堆栈并构建要存储到索引中的文档

可能的解决方案 一种解决方案是编写一种副本端点,其中应用程序将作为一个postgres实例,用于从原始数据库复制数据。有人对这种方法有经验吗

对于这个问题,我还有什么其他解决方案?

对于这个问题,我还有什么其他解决方案

用于告诉你的应用程序事情已经改变

您可以从一个触发器发送
通知
,该触发器还记录队列表中的更改

您需要一个PgJDBC连接,该连接已为您正在使用的事件发送了一个
LISTEN
。如果您使用SSL,它必须通过定期发送空查询(
)来轮询数据库;若您并没有使用SSL,那个么可以通过使用异步通知检查来避免这种情况。您需要从连接池中打开
连接
对象,才能将基础连接强制转换为
PgConnection
以使用侦听/通知。看

生产者/消费者部分将更加困难。要在PostgreSQL中拥有多个碰撞安全并发使用者,您需要将建议锁定与
pg\try\u advical\u lock(…)
一起使用。如果您不需要并发消费者,那么很容易,您只需
选择。。。每次更新一行的限制为1


希望9.4将包括一个更简单的方法,通过
更新
,跳过锁定的行,因为它正在开发中。

要使用LISTEN and NOTIFY of postgres,您需要使用一个支持异步通知的驱动程序。postgres JDBC驱动程序不支持异步通知

要通过应用服务器的通道持续侦听,请使用pgjdbc ng 0.6驱动程序


它支持异步通知,无需轮询

通常,我建议使用实现松耦合。然后,如果您决定交换数据库,则索引端的代码不会更改

如果您想使用紧耦合,我建议您使用 . 在Java中,使用非常重要,因为它支持异步 无轮询的通知

下面是一个异步模式(基于):


在其他语句中,您现在可以执行
notifytest,'这是一个有效负载'。您还可以在触发器等中执行
NOTIFY

仅针对记录
跳过锁定的
PG 9.5
中引入,避免使用管理功能,如
PG\u try\u advisional\u lock
。是的,尽管建议锁定仍然有一些非常方便的用途。你不必再像上面那样在排队时使用它们,但它们在其他领域仍然非常方便。
import com.impossibl.postgres.api.jdbc.PGConnection;
import com.impossibl.postgres.api.jdbc.PGNotificationListener;
import com.impossibl.postgres.jdbc.PGDataSource;    
import java.sql.Statement;

public static void listenToNotifyMessage() {
    PGDataSource dataSource = new PGDataSource();
    dataSource.setHost("localhost");
    dataSource.setPort(5432);
    dataSource.setDatabase("database_name");
    dataSource.setUser("postgres");
    dataSource.setPassword("password");

    PGNotificationListener listener = (int processId, String channelName, String payload) 
       -> System.out.println("notification = " + payload);

    try (PGConnection connection = (PGConnection) dataSource.getConnection()) {
        Statement statement = connection.createStatement();
        statement.execute("LISTEN test");
        statement.close();
        connection.addNotificationListener(listener);
        // it only works if the connection is open. Therefore, we do an endless loop here.
        while (true) {
           Thread.sleep(500);
       }
    } catch (Exception e) {
        System.err.println(e);
    }
}