Oracle JMS應用簡單案例(1)

Oracle端Code:

BEGIN

--定義隊列視圖,1.視圖名字自定義,2.視圖加載類型固定,3.其他參數
  DBMS_AQADM.CREATE_QUEUE_TABLE(QUEUE_TABLE        => 'epp_apply_queue_table',
                                QUEUE_PAYLOAD_TYPE => 'SYS.AQ$_JMS_MESSAGE',
                                MULTIPLE_CONSUMERS => FALSE);

--定義高級隊列,1.隊列名稱自定義,2.隊列視圖剛剛創建的
  DBMS_AQADM.CREATE_QUEUE(QUEUE_NAME  => '
epp_apply_queue',
                          QUEUE_TABLE => 'callhist_queue_table');

--開啓隊列 
  DBMS_AQADM.START_QUEUE(QUEUE_NAME => 'epp_apply_queue');

--關閉隊列

  DBMS_AQADM.stop_queue('epp_apply_queue');

END;


--創建觸發器,在執行數據插入與更新時,觸發JMS發送消息

create or replace trigger tri_eppApply_jsmDml before  INSERT or UPDATE
ON biz_fact_epp
  for each row
DECLARE
  -- local variables here
  ID                 PLS_INTEGER;
  AGENT              SYS.AQ$_AGENT := SYS.AQ$_AGENT(' ', NULL, 0);
  V_ERROR_CODE       VARCHAR2(2000);
  MESSAGE            SYS.AQ$_JMS_STREAM_MESSAGE; --SYS.AQ$_JMS_MESSAGE;
  ENQUEUE_OPTIONS    DBMS_AQ.ENQUEUE_OPTIONS_T;
  MESSAGE_PROPERTIES DBMS_AQ.MESSAGE_PROPERTIES_T;
  MSGID              RAW(16);
  content            varchar2(2000);
BEGIN
  -- Consturct a empty stream message object
  MESSAGE := SYS.AQ$_JMS_STREAM_MESSAGE.CONSTRUCT;
  -- Shows how to set the JMS header
  MESSAGE.SET_REPLYTO(AGENT);
  MESSAGE.SET_TYPE('tkaqpet1');
  MESSAGE.SET_USERID('jmsuser');
  MESSAGE.SET_APPID('plsql_enq');
  MESSAGE.SET_GROUPID('st');
  MESSAGE.SET_GROUPSEQ(1);

  -- Shows how to populate the message payload of aq$_jms_stream_message

  -- Passing -1 reserve a new slot within the message store of sys.aq$_jms_stream_message.
  -- The maximum number of sys.aq$_jms_stream_message type of messges to be operated at
  -- the same time within a session is 20. Calling clean_body function with parameter -1
  -- might result a ORA-24199 error if the messages currently operated is already 20.
  -- The user is responsible to call clean or clean_all function to clean up message store.
  ID := MESSAGE.CLEAR_BODY(-1);

  -- Write data into the message paylaod. These functions are analogy of JMS JAVA api's.
  -- See the document for detail.

  --編輯消息內容
   content := 'applyId=='||:new.APPLY_ID||'&&'||
              'listId=='||:new.LIST_ID||'&&'||
              'eppType=='||:new.EPP_TYPE||'&&'||
              'cardNo=='||:new.CARD_NO||'&&'||
              'status=='||:new.STATUS||'&&'||
              'createUser=='||:new.CREATE_USER||'&&'||
              'createTime=='||:new.CREATE_TIME||'&&'||
              'lastModifyUser=='||:new.LAST_MODIFY_USER||'&&'||
              'lastModifyTime=='||:new.LAST_MODIFY_TIME;
   MESSAGE.WRITE_STRING(ID,content);

  -- Write a byte to the stream message payload

  -- Write a String to the stream message payload

  -- Flush the data from JAVA stored procedure (JServ) to PL/SQL side
  -- Without doing this, the PL/SQL message is still empty.
  MESSAGE.FLUSH(ID);


  -- Use either clean_all or clean to clean up the message store when the user
  -- do not plan to do paylaod population on this message anymore
  SYS.AQ$_JMS_STREAM_MESSAGE.CLEAN_ALL();
  --message.clean(id);

  -- Enqueue this message into AQ queue using DBMS_AQ package

--消息發送語句
  DBMS_AQ.ENQUEUE(QUEUE_NAME         => 'epp_apply_queue',
                  ENQUEUE_OPTIONS    => ENQUEUE_OPTIONS,
                  MESSAGE_PROPERTIES => MESSAGE_PROPERTIES,
                  PAYLOAD            => MESSAGE,
                  MSGID              => MSGID);


  INSERT INTO LOG_PROC_ADQueue
    (PROC_EXECSN, 
    PROC_NAME, 
    START_TIME, 
    PROC_MSG,
    PROC_VERSION,
    queue_Name)
  VALUES
    (SYS_GUID(),
     'jms',
     SYSDATE,
     :new.APPLY_ID || '||' || MSGID || '||',
     TO_CHAR(SYSDATE, 'yyyy-mm-dd'),
     'epp_apply_queue');

EXCEPTION
  WHEN OTHERS THEN
    V_ERROR_CODE := 'SQLCODE='||SQLCODE||',SQLSTATE='||SQLERRM||',SQLERRM='||SQLERRM;
    INSERT INTO LOG_PROC_ADQueue
      (PROC_NAME,
       START_TIME,
       END_TIME,
       PROC_MSG,
       PROC_VERSION,
       queue_Name)
    VALUES
      ('jms_error',
       SYSDATE,
       SYSDATE,
       V_ERROR_CODE,
       TO_CHAR(SYSDATE, 'yyyy-mm-dd'),
       'epp_apply_queue');
END;


JAVA端:

加載 jms.jar aqapi.jar


創建工廠代碼

<span style="white-space:pre">	</span>private QueueConnectionFactory queueConnectionFactory = null;
<span style="white-space:pre">	</span>private QueueConnection queueConnection = null;
<span style="white-space:pre">	</span>private AQjmsSession queueSession = null;
<span style="white-space:pre">	</span>private boolean switcher = true;//turn on/off
<span style="white-space:pre">	</span>private Queue queue = null;
<span style="white-space:pre">	</span>private String queue_name; 
<span style="white-space:pre">	</span>private AQjmsQueueReceiver subscriber = null;
public boolean buildFactoryConnection(String queueName){
		boolean ret = false;
		//first read oracle properties;
		readDBProperties();
		//second create queue connection
		try {
			queueConnectionFactory = AQjmsFactory.getQueueConnectionFactory(
					ip, instance, port, connType);
			
			queueConnection = queueConnectionFactory.createQueueConnection(
					username, password);

			queueSession = (AQjmsSession) queueConnection.createQueueSession(false,
					Session.AUTO_ACKNOWLEDGE);
			
			queue = ((AQjmsSession) queueSession).getQueue(username,
					queueName);
			
			subscriber = (AQjmsQueueReceiver) queueSession.createReceiver(queue);
			
			queueConnection.start();   
			
			log.info("JMS connection queue:"+ queueName +" has started");
			this.queue_name = queueName;
			ret = true;//success return;
		} catch (JMSException e) {
			log.error("",e);
			ret = false;
		} 
		
		return ret;
	}
	
	private void readDBProperties(){
		Properties props = new Properties();
		try {
			props.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(CONFIGFILE));
			this.ip = props.getProperty(IPWORD);
			this.port = Integer.valueOf(props.getProperty(PORTWORD));
			this.instance = props.getProperty(INSWORD);
			this.connType = props.getProperty(CONNWORD);
			this.username = props.getProperty(USERWORD);
			this.password = props.getProperty(PASSWORD);
		} catch (IOException e) {
			log.error("IOException",e);
		}
	}


監聽隊列代碼

AQjmsStreamMessage message = null;

message = (AQjmsStreamMessage) subscriber.receive();//(AQjmsStreamMessage)msg;這裏具有阻塞功能,當沒有消息時,一直處於等待中直到接收到消息執行後續代碼。

String messageStr = message.readString();
log.info("Message:"+messageStr);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章