1

Java プログラムで非同期メッセージを渡したいので、最初のステップでは、DB 内のテーブルの変更を継続的に監視する必要があります。また、新しい受信メッセージがある場合は、それを表示する必要があります。これは、アプリケーションが実行されている限り、繰り返し処理する必要があります。

次のコードでこれを進める方法を知っているかもしれません.6秒ごとに無限に自分自身を呼び出し続けなければならず、データベースで新しい着信メッセージを見つける必要があるポーリングメソッドが含まれています.

コードスニペットは次のとおりです。

public class PollingSynchronizer implements Runnable {

private Collection<KPIMessage> incomingMessages;
private Connection dbConnection;


/**
 * Constructor. Requires to provide a reference to the KA message queue
 * 
 * @param incomingMessages reference to message queue
 * 
 */
   public PollingSynchronizer(Collection<KpiMessage> incomingMessages, Connection dbConnection) {
    super();
    this.incomingMessages = incomingMessages;
    this.dbConnection = dbConnection;
}

private int sequenceId;

public int getSequenceId() {
    return sequenceId;
}

public void setSequenceId(int sequenceId) {
    this.sequenceId = sequenceId;
}



@Override
/**
 * The method which runs Polling action and record the time at which it is done
 * 
 */
public void run() {
    try {


           incomingMessages.addAll(fullPoll());
            System.out.println("waiting 6 seconds");

            //perform this operation in a loop
            Thread.sleep(6000);

    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
    Date currentDate = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS");
//  System.out.println(sdf.format(currentDate) + " " + msg);
}

/**
 * Method which defines polling of the database and also count the number of Queries
 * @return 
 * @throws Exception
 */
public List<KpiMessage> fullPoll() throws Exception {

//  int sequenceID = 0;
    Statement st = dbConnection.createStatement();

    ResultSet rs = st.executeQuery("select * from msg_new_to_bde where ACTION = 804 order by SEQ DESC");
        List<KpiMessage> pojoCol = new ArrayList<KpiMessage>();
        while (rs.next()) {
            KpiMessage filedClass = convertRecordsetToPojo(rs);
            pojoCol.add(filedClass);
        }

        return pojoCol;
        }

/**
 * Converts a provided record-set to a {@link KpiMessage}.
 * 
 * The following attributes are copied from record-set to pojo:
 * 
 * <ul>
 * <li>SEQ</li>
 * <li>TABLENAME</li>
 * <li>ENTRYTIME</li>
 * <li>STATUS</li>
 * </ul>
 * 
 * @param rs
 *            the recordset to convert
 * @return the converted pojo class object
 * @throws SQLException
 *             if an sql error occurrs during processing of recordset
 */
private KpiMessage convertRecordsetToPojo(ResultSet rs) throws SQLException {

    KpiMessage msg = new KpiMessage();
    int sequence = rs.getInt("SEQ");
    msg.setSequence(sequence);
    int action = rs.getInt("ACTION");
    msg.setAction(action);
    String tablename = rs.getString("TABLENAME");
    msg.setTableName(tablename);
    Timestamp entrytime = rs.getTimestamp("ENTRYTIME");
    Date entryTime = new Date(entrytime.getTime());
    msg.setEntryTime(entryTime);
    Timestamp processingtime = rs.getTimestamp("PROCESSINGTIME");
    if (processingtime != null) {
        Date processingTime = new Date(processingtime.getTime());
        msg.setProcessingTime(processingTime);
    }
    String keyInfo1 = rs.getString("KEYINFO1");
    msg.setKeyInfo1(keyInfo1);
    String keyInfo2 = rs.getString("KEYINFO2");
    msg.setKeyInfo2(keyInfo2);
    return msg;
}
}

ここで、シーケンス ID はテーブル内の一意の ID であり、新しい受信メッセージが到着するにつれて増加し続けます。

PS : 「お願い : 否定的な評価を付ける理由を教えてください (親指を下に向けてください)。私の質問を明確に説明できるように」

4

2 に答える 2

1

簡単に while(true) ループに入れます。

public void run() {
    while(true){
        try {


               incomingMessages.addAll(fullPoll());
                System.out.println("waiting 6 seconds");

                //perform this operation in a loop
                Thread.sleep(6000);

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        Date currentDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS");
    //  System.out.println(sdf.format(currentDate) + " " + msg);
   }
}

Runnable を新しいスレッドとしてすでに開始していることを願っています。

新規および更新されたメッセージには、データベース内の「last_update」などのフィールドが必要です。新しいメッセージを確認するたびに、新しいメッセージを取得するための SQL ステートメントを次のように変更する必要がありwhere last_update > $lastCheckedDateます。lastCheckedDate

Java の同時実行性について何か読みたいと思うかもしれません: http://docs.oracle.com/javase/tutorial/essential/concurrency/

于 2013-01-07T09:35:25.070 に答える
0

whileループを入れるのも一つの方法ですが、そういうやり方は避けたほうがいいと思います(トランザクションなどめちゃくちゃな事が多い)。

このような反復的な作業が本当に必要な場合は、スケジューラの使用を検討してください。Spring 3.x にはスケジューラが組み込まれていますが、Quartz も使用できます。

さらに良い方法は、このようなポーリングを避けることです。データが更新されたときに JMS キューにメッセージを入れて、JMS キューにそのようなメッセージがあるとロジックが (メッセージ駆動型 Bean を介して) 呼び出されるようにすることはできますか? (可能な方法は1つだけで、同様の方法がたくさんあります)

于 2013-01-07T09:44:15.473 に答える