2

在这里,我有线程池和另一个轮询类,用于实现轮询和从数据库中读取消息。现在的问题是我必须避免读取冗余消息以进行更新并同时处理等待的其他消息,因为有大量消息在等待。

// the code for poll method
public void poll() throws Exception {
    // Method which defines polling of the data entry for counting its size.
    st = conn.createStatement();
    int count = 1;
    long waitInMillisec = 1 * 60 * 125; // Wait for 7.5 seconds.
    for (int i = 0; i < count; i++) {
        System.out.println("Wait for " + waitInMillisec + " millisec");
        Thread.sleep(waitInMillisec);

        java.util.Date date = new java.util.Date();
        Timestamp start = new Timestamp(date.getTime());
        rs = st.executeQuery("select * from msg_new_to_bde where ACTION=804");
        java.util.Date date1 = new java.util.Date();
        Timestamp end = new Timestamp(date1.getTime());
        System.out.print("Query count: ");
        System.out.println(end.getTime() - start.getTime());

        Collection<KpiMessage> pojoCol = new ArrayList<KpiMessage>();
        while (rs.next()) {
            KpiMessage filedClass = convertRecordsetToPojo(rs);
            pojoCol.add(filedClass);

        }
4

1 回答 1

0

我不知道您是否可以选择消息的存储方式,但它们似乎已插入到您正在轮询的表中。您可以向该表添加一个数据库触发器,然后将一条消息推送到具有相同数据和相关 ID 的 Oracle AQ。

如果您可以不使用该表,我建议您只在相同的模式中定义 Oracle AQ 来存储消息,并使用像 corrid="804%" 这样的模式匹配通过部分相关 id 出列。AQ 消息的完整相关 id 可能是“804”+ 消息的唯一 pk。然后,您可以将同一队列重用于多个操作,并定义一个 Java 队列 804 操作工作程序类来等待该特定操作的消息(AQ 消息上的 804 相关 id 前缀)。

Oracle for AQ 的文档非常好,用于创建队列的包是 dbms_aqadm。用于入队/出队的包是 dbms_aq。在创建 aq 和使用 dbms_aq 包之前,您还需要获得一些 priv/grants。dbms_aq 应该可以很容易地从 Java 中调用。

转至 docs.oracle.com 以查找有关 dbms_aqadm 和 dbms_aq 包的详细信息。一旦你创建了 AQ(这将创建一个支持队列的 AQ 表),我建议你在 corrid 上为 AQ 表添加一个索引以提高性能。

如果您无法避免现有的表架构或不想使用 AQ 技术,您可以使用的另一个选项是在 Oracle(dbms_lock 包)中创建一个锁并在轮询类中调用它来获取锁或阻塞/等待。这样,您可以同步所有轮询类,以避免多个线程接收同一条消息。所以轮询类要做的第一件事就是尝试获取锁,如果成功,它会从表中拉出一条消息,处理它,在处理后更新它,释放锁。dbms_lock 包可以阻塞/等待锁定或立即返回,但根据操作成功/失败,您可以采取进一步的行动。但它会帮助您控制线程接收相同的消息。Oracle 的文档在这个包上也很不错。

于 2014-08-16T14:34:36.233 回答