Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

Oracle एपेक्स के भीतर Oracle DBMS_ALERT का उपयोग कैसे करें?

मैं एपेक्स.ओरेकल.कॉम पर एक डेमो सेट अप करूंगा, लेकिन चूंकि आपको dbms_alert पर एक्ज़ीक्यूट ग्रांट की आवश्यकता है, इसलिए इसे केवल टेक्स्ट के रूप में होना चाहिए।

आप पूरे सेट-अप के साथ काफी दूर जा सकते हैं, इसलिए मैं इसे मूल बातें मानूंगा। उदाहरण के लिए, मैंने केवल एक अलर्ट के साथ काम किया है। अपने नमूने में आप विभिन्न प्रगति अलर्ट को पकड़ने के लिए कई ईवेंट का उपयोग करना चाह सकते हैं। यह साधारण कारण के लिए है कि क्लाइंट (AJAX प्रतिक्रिया) को कुछ वापस करने के लिए AJAX कॉलबैक को 'बंद' करना पड़ता है। तो जब कोई अलर्ट पकड़ता है और उसे वापस करना चाहता है, तो आपको बफर को लिखना होगा और इसे वापस करना होगा। इसका मतलब है कि आप घटना को सुनना भी बंद कर देंगे (पढ़ें:शीर्ष में, आपको चाहिए!)

इस तरह के प्रवाह पर विचार करें:आप एक अजाक्स कॉल करेंगे, और एक अजाक्स कॉलबैक प्रक्रिया होगी जो किसी घटना में रुचि दर्ज करती है। फिर आप अलर्ट होने की प्रतीक्षा करते हैं। आप इसे पकड़ते हैं और इसे http बफर में लिखकर वापस कर देते हैं (htp.p ) यह कोड का अंत है और एपेक्स बफर को फ्लश करेगा, अजाक्स कॉल तब प्रतिक्रिया उठाएगी और आप उस रिटर्न को प्रबंधित करने में सक्षम होंगे। हालांकि मत भूलना:एपेक्स कनेक्शन पूलिंग और डेटाबेस का उपयोग करता है सत्र सीधे जुड़े नहीं हैं बल्कि हर समय पुन:उपयोग किए जाते हैं। आप डेटाबेस सत्र 'गंदे' को 'छोड़ना' नहीं चाहते हैं। आपको अपना अलर्ट-ब्याज भी अपंजीकृत करना होगा। यह अलर्ट के लिए अद्वितीय आईडी का उपयोग करने के लिए भी एक मामला बनाता है - अलर्ट को विभिन्न (डेटाबेस) सत्रों में पंजीकृत किया जा सकता है, इसलिए यदि यह एक ऐसा पृष्ठ होगा जिसका उपयोग कई उपयोगकर्ता अपनी प्रक्रिया की प्रगति की प्रगति का पालन करने के लिए कर सकते हैं, तो आप ऐसा नहीं करते हैं चाहते हैं कि वे अन्य उपयोगकर्ताओं के अलर्ट में हस्तक्षेप करें।

हालांकि, ब्याज की इस क्षणभंगुर प्रकृति का अर्थ यह भी है कि विभिन्न अजाक्स कॉलों के बीच "रुकावट" होंगे। जब आप कई अलर्ट सुनना चाहते हैं, और ये अलर्ट एक साथ बहुत करीब से पैक किए जा सकते हैं, तो मौका मौजूद है कि आप एक से चूक सकते हैं। मान लें कि 2 अलर्ट 1ms अलग हैं:पहला पकड़ा जाएगा, अजाक्स कॉल को रिपोर्ट किया जाएगा, जिसे अधिक अलर्ट सुनने के लिए तुरंत एक नया कॉल शुरू करना होगा। लेकिन चूंकि उस कम समय के दौरान कोई सक्रिय श्रोता नहीं था, हो सकता है कि अगला अलर्ट छूट गया हो। अब - यह केवल एक मुद्दा होने की संभावना है जहां आप एक ही हैंडलर के तहत कई अलर्ट बंद कर देते हैं। यदि आप एक से अधिक हैंडलर का उपयोग करते हैं और एक ही समय में उन सभी के लिए अजाक्स कॉल शुरू करते हैं, तो वे सभी समय पर संभाले जाएंगे। दोनों के लिए समाधान हैं, बिल्कुल। मैं कल्पना करता हूं कि केवल एक हैंडलर का उपयोग करते समय आप संग्रह में सभी अलर्ट पकड़ सकते हैं और इसके खिलाफ जांच कर सकते हैं कि क्या आपने पहले ही किसी निश्चित अलर्ट के लिए प्रतिक्रिया भेज दी है या नहीं और चेक इन करना जारी रखना है या नहीं। एकाधिक हैंडलर के साथ आप एक अद्वितीय आईडी का उपयोग कर सकते हैं और इसे विभिन्न स्थितियों के साथ प्रत्ययित कर सकते हैं।

तो यहाँ कुछ वास्तविक कोड है जिसका उपयोग मैंने अपने स्थानीय POC में किया है।

अवलोकन:मेरे पास 3 बटन हैं:1 एक अलर्ट आईडी उत्पन्न करने के लिए, जिसके लिए मैंने एक अनुक्रम का उपयोग किया था। किसी ईवेंट को सुनना शुरू करने के लिए एक और बटन, और अलर्ट भेजने के लिए एक और बटन।

NEW_ALERT_ID बटन के लिए JS कोड:

apex.server.process("NEW_ALERT").done(function(pdata){
$s("P1_ALERT_ID",pdata.alertId);
})

START_LISTEN बटन के लिए JS कोड:

apex.server.process("LISTEN_ALERT",{x01:$v("P1_ALERT_ID")},{timeout:(31*1000)})
.done(function(pdata){
  if (pdata.success ){
      alert('Caught alert: ' + pdata.message);
  } else {
      alert("No alerts caught during wait on database. You may want to continue listening in...")
  }
})
.fail(function(jqXHR, textStatus){
    if(textStatus === 'timeout')
    {     
        alert('Call should have returned by now...'); 
        //do something. Try again perhaps?
    }
});

SEND_ALERT बटन के लिए JS कोड:

apex.server.process("SEND_ALERT",{x01:$v("P1_ALERT_ID")},{dataType:"text"});

AJAX कॉलबैक प्रक्रिया:

NEW_ALERT:

htp.p('{"alertId":'||alert_seq.nextval()||'}');

LISTEN_ALERT:

declare
  alert_id number := apex_application.g_x01;
  msg varchar2(2000);
  stat pls_integer;
  keep_looping boolean := true;
  insurance binary_integer := 0; -- prevent an infinite loop

  onecycle binary_integer := 3; -- one cycle of waiting, in seconds
  maxcycles binary_integer := 10; -- in this session, the max amount of cycles to wait
begin
  dbms_alert.register(alert_id);

  while keep_looping
  loop
    insurance := insurance + 1;

    dbms_alert.waitone(alert_id, msg, stat, onecycle);
    if stat = 1 then
      apex_debug.message('timeout occured, going again');
    else
      apex_debug.message('alert: '||msg);
      keep_looping := false;
    end if;

    exit when insurance = maxcycles;    
  end loop;


  if keep_looping then
    -- we waited a really long time now. It may be a good idea to return this info to the client and let it start a new call
    htp.p('{"success":false,"message":"No alert during wait on database"}');
  else
    htp.p('{"success":true,"message":"'||msg||'"}');
  end if;
end;

SEND_ALERT:

declare
  alert_id number := apex_application.g_x01;
begin
  dbms_alert.signal(alert_id, 'alert sent at '||to_char(systimestamp, 'HH24:MI:SS FF6'));
end;

तो, मुझे पहले एक अलर्ट आईडी मिलेगा, फिर मैं सुनना शुरू करूंगा, और फिर किसी बिंदु पर मैं एक अलर्ट (या नहीं) भेजूंगा। हालांकि यह एक कंकाल है और इसे आपके वास्तविक सेटअप में और परिशोधन की आवश्यकता होगी।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle के लिए संपूर्ण स्कीमा के सभी क्षेत्रों में दिए गए स्ट्रिंग की खोज करें

  2. विंडोज़ पर Oracle डाटाबेस कैसे स्थापित करें

  3. क्या 10g सर्वर के साथ oracle 11g क्लाइंट का उपयोग करना ठीक है?

  4. वृद्धिशील डेटाबेस परिवर्तन का पता लगाना (Oracle to MongoDB ETL)

  5. त्रुटि (2,7):PLS-00428:इस चयन कथन में एक INTO खंड अपेक्षित है